FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
tinyxml.h
1 /*
2 www.sourceforge.net/projects/tinyxml
3 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
4 
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any
7 damages arising from the use of this software.
8 
9 Permission is granted to anyone to use this software for any
10 purpose, including commercial applications, and to alter it and
11 redistribute it freely, subject to the following restrictions:
12 
13 1. The origin of this software must not be misrepresented; you must
14 not claim that you wrote the original software. If you use this
15 software in a product, an acknowledgment in the product documentation
16 would be appreciated but is not required.
17 
18 2. Altered source versions must be plainly marked as such, and
19 must not be misrepresented as being the original software.
20 
21 3. This notice may not be removed or altered from any source
22 distribution.
23 */
24 
25 
26 #ifndef TINYXML_INCLUDED
27 #define TINYXML_INCLUDED
28 
29 #ifdef _MSC_VER
30 #pragma warning( push )
31 #pragma warning( disable : 4530 )
32 #pragma warning( disable : 4786 )
33 #endif
34 
35 #include <ctype.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <assert.h>
40 
41 // Help out windows:
42 #if defined( _DEBUG ) && !defined( DEBUG )
43 #define DEBUG
44 #endif
45 
46 #ifdef TIXML_USE_STL
47  #include <string>
48  #include <iostream>
49  #include <sstream>
50  #define TIXML_STRING std::string
51 #else
52  #include "tinystr.h"
53  #define TIXML_STRING TiXmlString
54 #endif
55 
56 // Deprecated library function hell. Compilers want to use the
57 // new safe versions. This probably doesn't fully address the problem,
58 // but it gets closer. There are too many compilers for me to fully
59 // test. If you get compilation troubles, undefine TIXML_SAFE
60 #define TIXML_SAFE
61 
62 #ifdef TIXML_SAFE
63  #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
64  // Microsoft visual studio, version 2005 and higher.
65  #define TIXML_SNPRINTF _snprintf_s
66  #define TIXML_SNSCANF _snscanf_s
67  #define TIXML_SSCANF sscanf_s
68  #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
69  // Microsoft visual studio, version 6 and higher.
70  //#pragma message( "Using _sn* functions." )
71  #define TIXML_SNPRINTF _snprintf
72  #define TIXML_SNSCANF _snscanf
73  #define TIXML_SSCANF sscanf
74  #elif defined(__GNUC__) && (__GNUC__ >= 3 )
75  // GCC version 3 and higher.s
76  //#warning( "Using sn* functions." )
77  #define TIXML_SNPRINTF snprintf
78  #define TIXML_SNSCANF snscanf
79  #define TIXML_SSCANF sscanf
80  #else
81  #define TIXML_SSCANF sscanf
82  #endif
83 #endif
84 
85 class TiXmlDocument;
86 class TiXmlElement;
87 class TiXmlComment;
88 class TiXmlUnknown;
89 class TiXmlAttribute;
90 class TiXmlText;
91 class TiXmlDeclaration;
92 class TiXmlParsingData;
93 
94 const int TIXML_MAJOR_VERSION = 2;
95 const int TIXML_MINOR_VERSION = 5;
96 const int TIXML_PATCH_VERSION = 3;
97 
98 /* Internal structure for tracking location of items
99  in the XML file.
100 */
101 struct TiXmlCursor
102 {
103  TiXmlCursor() { Clear(); }
104  void Clear() { row = col = -1; }
105 
106  int row; // 0 based.
107  int col; // 0 based.
108 };
109 
110 
130 {
131 public:
132  virtual ~TiXmlVisitor() {}
133 
135  virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; }
137  virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; }
138 
140  virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; }
142  virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; }
143 
145  virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; }
147  virtual bool Visit( const TiXmlText& /*text*/ ) { return true; }
149  virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; }
151  virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; }
152 };
153 
154 // Only used by Attribute::Query functions
155 enum
156 {
157  TIXML_SUCCESS,
158  TIXML_NO_ATTRIBUTE,
159  TIXML_WRONG_TYPE
160 };
161 
162 
163 // Used by the parsing routines.
164 enum TiXmlEncoding
165 {
166  TIXML_ENCODING_UNKNOWN,
167  TIXML_ENCODING_UTF8,
168  TIXML_ENCODING_LEGACY
169 };
170 
171 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
172 
196 {
197  friend class TiXmlNode;
198  friend class TiXmlElement;
199  friend class TiXmlDocument;
200 
201 public:
202  TiXmlBase() : userData(0) {}
203  virtual ~TiXmlBase() {}
204 
214  virtual void Print( FILE* cfile, int depth ) const = 0;
215 
222  static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
223 
225  static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
226 
245  int Row() const { return location.row + 1; }
246  int Column() const { return location.col + 1; }
247 
248  void SetUserData( void* user ) { userData = user; }
249  void* GetUserData() { return userData; }
250  const void* GetUserData() const { return userData; }
251 
252  // Table that returs, for a given lead byte, the total number of bytes
253  // in the UTF-8 sequence.
254  static const int utf8ByteTable[256];
255 
256  virtual const char* Parse( const char* p,
257  TiXmlParsingData* data,
258  TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
259 
263  static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
264 
265  enum
266  {
267  TIXML_NO_ERROR = 0,
268  TIXML_ERROR,
269  TIXML_ERROR_OPENING_FILE,
270  TIXML_ERROR_OUT_OF_MEMORY,
271  TIXML_ERROR_PARSING_ELEMENT,
272  TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
273  TIXML_ERROR_READING_ELEMENT_VALUE,
274  TIXML_ERROR_READING_ATTRIBUTES,
275  TIXML_ERROR_PARSING_EMPTY,
276  TIXML_ERROR_READING_END_TAG,
277  TIXML_ERROR_PARSING_UNKNOWN,
278  TIXML_ERROR_PARSING_COMMENT,
279  TIXML_ERROR_PARSING_DECLARATION,
280  TIXML_ERROR_DOCUMENT_EMPTY,
281  TIXML_ERROR_EMBEDDED_NULL,
282  TIXML_ERROR_PARSING_CDATA,
283  TIXML_ERROR_DOCUMENT_TOP_ONLY,
284 
285  TIXML_ERROR_STRING_COUNT
286  };
287 
288 protected:
289 
290  static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
291  inline static bool IsWhiteSpace( char c )
292  {
293  return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
294  }
295  inline static bool IsWhiteSpace( int c )
296  {
297  if ( c < 256 )
298  return IsWhiteSpace( (char) c );
299  return false; // Again, only truly correct for English/Latin...but usually works.
300  }
301 
302  #ifdef TIXML_USE_STL
303  static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
304  static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
305  #endif
306 
307  /* Reads an XML name into the string provided. Returns
308  a pointer just past the last character of the name,
309  or 0 if the function has an error.
310  */
311  static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
312 
313  /* Reads text. Returns a pointer past the given end tag.
314  Wickedly complex options, but it keeps the (sensitive) code in one place.
315  */
316  static const char* ReadText( const char* in, // where to start
317  TIXML_STRING* text, // the string read
318  bool ignoreWhiteSpace, // whether to keep the white space
319  const char* endTag, // what ends this text
320  bool ignoreCase, // whether to ignore case in the end tag
321  TiXmlEncoding encoding ); // the current encoding
322 
323  // If an entity has been found, transform it into a character.
324  static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
325 
326  // Get a character, while interpreting entities.
327  // The length can be from 0 to 4 bytes.
328  inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
329  {
330  assert( p );
331  if ( encoding == TIXML_ENCODING_UTF8 )
332  {
333  *length = utf8ByteTable[ *((const unsigned char*)p) ];
334  assert( *length >= 0 && *length < 5 );
335  }
336  else
337  {
338  *length = 1;
339  }
340 
341  if ( *length == 1 )
342  {
343  if ( *p == '&' )
344  return GetEntity( p, _value, length, encoding );
345  *_value = *p;
346  return p+1;
347  }
348  else if ( *length )
349  {
350  //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe),
351  // and the null terminator isn't needed
352  for( int i=0; p[i] && i<*length; ++i ) {
353  _value[i] = p[i];
354  }
355  return p + (*length);
356  }
357  else
358  {
359  // Not valid text.
360  return 0;
361  }
362  }
363 
364  // Return true if the next characters in the stream are any of the endTag sequences.
365  // Ignore case only works for english, and should only be relied on when comparing
366  // to English words: StringEqual( p, "version", true ) is fine.
367  static bool StringEqual( const char* p,
368  const char* endTag,
369  bool ignoreCase,
370  TiXmlEncoding encoding );
371 
372  static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
373 
374  TiXmlCursor location;
375 
377  void* userData;
378 
379  // None of these methods are reliable for any language except English.
380  // Good for approximation, not great for accuracy.
381  static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
382  static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
383  inline static int ToLower( int v, TiXmlEncoding encoding )
384  {
385  if ( encoding == TIXML_ENCODING_UTF8 )
386  {
387  if ( v < 128 ) return tolower( v );
388  return v;
389  }
390  else
391  {
392  return tolower( v );
393  }
394  }
395  static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
396 
397 private:
398  TiXmlBase( const TiXmlBase& ); // not implemented.
399  void operator=( const TiXmlBase& base ); // not allowed.
400 
401  struct Entity
402  {
403  const char* str;
404  unsigned int strLength;
405  char chr;
406  };
407  enum
408  {
409  NUM_ENTITY = 5,
410  MAX_ENTITY_LENGTH = 6
411 
412  };
413  static Entity entity[ NUM_ENTITY ];
414  static bool condenseWhiteSpace;
415 };
416 
417 
424 class TiXmlNode : public TiXmlBase
425 {
426  friend class TiXmlDocument;
427  friend class TiXmlElement;
428 
429 public:
430  #ifdef TIXML_USE_STL
431 
435  friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
436 
453  friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
454 
456  friend std::string& operator<< (std::string& out, const TiXmlNode& base );
457 
458  #endif
459 
463  enum NodeType
464  {
465  DOCUMENT,
466  ELEMENT,
467  COMMENT,
468  UNKNOWN,
469  TEXT,
470  DECLARATION,
471  TYPECOUNT
472  };
473 
474  virtual ~TiXmlNode();
475 
488  const char *Value() const { return value.c_str (); }
489 
490  #ifdef TIXML_USE_STL
491 
495  const std::string& ValueStr() const { return value; }
496  #endif
497 
498  const TIXML_STRING& ValueTStr() const { return value; }
499 
509  void SetValue(const char * _value) { value = _value;}
510 
511  #ifdef TIXML_USE_STL
512  void SetValue( const std::string& _value ) { value = _value; }
514  #endif
515 
517  void Clear();
518 
520  TiXmlNode* Parent() { return parent; }
521  const TiXmlNode* Parent() const { return parent; }
522 
523  const TiXmlNode* FirstChild() const { return firstChild; }
524  TiXmlNode* FirstChild() { return firstChild; }
525  const TiXmlNode* FirstChild( const char * value ) const;
526  TiXmlNode* FirstChild( const char * _value ) {
528  // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
529  // call the method, cast the return back to non-const.
530  return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
531  }
532  const TiXmlNode* LastChild() const { return lastChild; }
533  TiXmlNode* LastChild() { return lastChild; }
534 
535  const TiXmlNode* LastChild( const char * value ) const;
536  TiXmlNode* LastChild( const char * _value ) {
537  return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
538  }
539 
540  #ifdef TIXML_USE_STL
541  const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); }
542  TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); }
543  const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); }
544  TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); }
545  #endif
546 
563  const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
564  TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
565  return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
566  }
567 
569  const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
570  TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
571  return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
572  }
573 
574  #ifdef TIXML_USE_STL
575  const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); }
576  TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); }
577  #endif
578 
582  TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
583 
584 
594  TiXmlNode* LinkEndChild( TiXmlNode* addThis );
595 
599  TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
600 
604  TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
605 
609  TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
610 
612  bool RemoveChild( TiXmlNode* removeThis );
613 
615  const TiXmlNode* PreviousSibling() const { return prev; }
616  TiXmlNode* PreviousSibling() { return prev; }
617 
619  const TiXmlNode* PreviousSibling( const char * ) const;
620  TiXmlNode* PreviousSibling( const char *_prev ) {
621  return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
622  }
623 
624  #ifdef TIXML_USE_STL
625  const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); }
626  TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); }
627  const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); }
628  TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); }
629  #endif
630 
632  const TiXmlNode* NextSibling() const { return next; }
633  TiXmlNode* NextSibling() { return next; }
634 
636  const TiXmlNode* NextSibling( const char * ) const;
637  TiXmlNode* NextSibling( const char* _next ) {
638  return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
639  }
640 
645  const TiXmlElement* NextSiblingElement() const;
647  return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
648  }
649 
654  const TiXmlElement* NextSiblingElement( const char * ) const;
655  TiXmlElement* NextSiblingElement( const char *_next ) {
656  return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
657  }
658 
659  #ifdef TIXML_USE_STL
660  const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); }
661  TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); }
662  #endif
663 
665  const TiXmlElement* FirstChildElement() const;
667  return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
668  }
669 
671  const TiXmlElement* FirstChildElement( const char * _value ) const;
672  TiXmlElement* FirstChildElement( const char * _value ) {
673  return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
674  }
675 
676  #ifdef TIXML_USE_STL
677  const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); }
678  TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); }
679  #endif
680 
685  int Type() const { return type; }
686 
690  const TiXmlDocument* GetDocument() const;
692  return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
693  }
694 
696  bool NoChildren() const { return !firstChild; }
697 
698  virtual const TiXmlDocument* ToDocument() const { return 0; }
699  virtual const TiXmlElement* ToElement() const { return 0; }
700  virtual const TiXmlComment* ToComment() const { return 0; }
701  virtual const TiXmlUnknown* ToUnknown() const { return 0; }
702  virtual const TiXmlText* ToText() const { return 0; }
703  virtual const TiXmlDeclaration* ToDeclaration() const { return 0; }
704 
705  virtual TiXmlDocument* ToDocument() { return 0; }
706  virtual TiXmlElement* ToElement() { return 0; }
707  virtual TiXmlComment* ToComment() { return 0; }
708  virtual TiXmlUnknown* ToUnknown() { return 0; }
709  virtual TiXmlText* ToText() { return 0; }
710  virtual TiXmlDeclaration* ToDeclaration() { return 0; }
711 
715  virtual TiXmlNode* Clone() const = 0;
716 
739  virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
740 
741 protected:
742  TiXmlNode( NodeType _type );
743 
744  // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
745  // and the assignment operator.
746  void CopyTo( TiXmlNode* target ) const;
747 
748  #ifdef TIXML_USE_STL
749  // The real work of the input operator.
750  virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
751  #endif
752 
753  // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
754  TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
755 
756  TiXmlNode* parent;
757  NodeType type;
758 
759  TiXmlNode* firstChild;
760  TiXmlNode* lastChild;
761 
762  TIXML_STRING value;
763 
764  TiXmlNode* prev;
765  TiXmlNode* next;
766 
767 private:
768  TiXmlNode( const TiXmlNode& ); // not implemented.
769  void operator=( const TiXmlNode& base ); // not allowed.
770 };
771 
772 
780 class TiXmlAttribute : public TiXmlBase
781 {
782  friend class TiXmlAttributeSet;
783 
784 public:
787  {
788  document = 0;
789  prev = next = 0;
790  }
791 
792  #ifdef TIXML_USE_STL
793  TiXmlAttribute( const std::string& _name, const std::string& _value )
795  {
796  name = _name;
797  value = _value;
798  document = 0;
799  prev = next = 0;
800  }
801  #endif
802 
804  TiXmlAttribute( const char * _name, const char * _value )
805  {
806  name = _name;
807  value = _value;
808  document = 0;
809  prev = next = 0;
810  }
811 
812  const char* Name() const { return name.c_str(); }
813  const char* Value() const { return value.c_str(); }
814  #ifdef TIXML_USE_STL
815  const std::string& ValueStr() const { return value; }
816  #endif
817  int IntValue() const;
818  double DoubleValue() const;
819 
820  // Get the tinyxml string representation
821  const TIXML_STRING& NameTStr() const { return name; }
822 
832  int QueryIntValue( int* _value ) const;
834  int QueryDoubleValue( double* _value ) const;
835 
836  void SetName( const char* _name ) { name = _name; }
837  void SetValue( const char* _value ) { value = _value; }
838 
839  void SetIntValue( int _value );
840  void SetDoubleValue( double _value );
841 
842  #ifdef TIXML_USE_STL
843  void SetName( const std::string& _name ) { name = _name; }
846  void SetValue( const std::string& _value ) { value = _value; }
847  #endif
848 
850  const TiXmlAttribute* Next() const;
851  TiXmlAttribute* Next() {
852  return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
853  }
854 
856  const TiXmlAttribute* Previous() const;
858  return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
859  }
860 
861  bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
862  bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
863  bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
864 
865  /* Attribute parsing starts: first letter of the name
866  returns: the next char after the value end quote
867  */
868  virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
869 
870  // Prints this Attribute to a FILE stream.
871  virtual void Print( FILE* cfile, int depth ) const {
872  Print( cfile, depth, 0 );
873  }
874  void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
875 
876  // [internal use]
877  // Set the document pointer so the attribute can report errors.
878  void SetDocument( TiXmlDocument* doc ) { document = doc; }
879 
880 private:
881  TiXmlAttribute( const TiXmlAttribute& ); // not implemented.
882  void operator=( const TiXmlAttribute& base ); // not allowed.
883 
884  TiXmlDocument* document; // A pointer back to a document, for error reporting.
885  TIXML_STRING name;
886  TIXML_STRING value;
887  TiXmlAttribute* prev;
888  TiXmlAttribute* next;
889 };
890 
891 
892 /* A class used to manage a group of attributes.
893  It is only used internally, both by the ELEMENT and the DECLARATION.
894 
895  The set can be changed transparent to the Element and Declaration
896  classes that use it, but NOT transparent to the Attribute
897  which has to implement a next() and previous() method. Which makes
898  it a bit problematic and prevents the use of STL.
899 
900  This version is implemented with circular lists because:
901  - I like circular lists
902  - it demonstrates some independence from the (typical) doubly linked list.
903 */
904 class TiXmlAttributeSet
905 {
906 public:
907  TiXmlAttributeSet();
908  ~TiXmlAttributeSet();
909 
910  void Add( TiXmlAttribute* attribute );
911  void Remove( TiXmlAttribute* attribute );
912 
913  const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
914  TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
915  const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
916  TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
917 
918  const TiXmlAttribute* Find( const char* _name ) const;
919  TiXmlAttribute* Find( const char* _name ) {
920  return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
921  }
922  #ifdef TIXML_USE_STL
923  const TiXmlAttribute* Find( const std::string& _name ) const;
924  TiXmlAttribute* Find( const std::string& _name ) {
925  return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
926  }
927 
928  #endif
929 
930 private:
931  //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
932  //*ME: this class must be also use a hidden/disabled copy-constructor !!!
933  TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed
934  void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
935 
936  TiXmlAttribute sentinel;
937 };
938 
939 
944 class TiXmlElement : public TiXmlNode
945 {
946 public:
948  TiXmlElement (const char * in_value);
949 
950  #ifdef TIXML_USE_STL
951  TiXmlElement( const std::string& _value );
953  #endif
954 
955  TiXmlElement( const TiXmlElement& );
956 
957  void operator=( const TiXmlElement& base );
958 
959  virtual ~TiXmlElement();
960 
964  const char* Attribute( const char* name ) const;
965 
972  const char* Attribute( const char* name, int* i ) const;
973 
980  const char* Attribute( const char* name, double* d ) const;
981 
989  int QueryIntAttribute( const char* name, int* _value ) const;
991  int QueryDoubleAttribute( const char* name, double* _value ) const;
993  int QueryFloatAttribute( const char* name, float* _value ) const {
994  double d;
995  int result = QueryDoubleAttribute( name, &d );
996  if ( result == TIXML_SUCCESS ) {
997  *_value = (float)d;
998  }
999  return result;
1000  }
1001 
1002  #ifdef TIXML_USE_STL
1003 
1011  template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
1012  {
1013  const TiXmlAttribute* node = attributeSet.Find( name );
1014  if ( !node )
1015  return TIXML_NO_ATTRIBUTE;
1016 
1017  std::stringstream sstream( node->ValueStr() );
1018  sstream >> *outValue;
1019  if ( !sstream.fail() )
1020  return TIXML_SUCCESS;
1021  return TIXML_WRONG_TYPE;
1022  }
1023  /*
1024  This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string"
1025  but template specialization is hard to get working cross-compiler. Leaving the bug for now.
1026 
1027  // The above will fail for std::string because the space character is used as a seperator.
1028  // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string
1029  template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const
1030  {
1031  const TiXmlAttribute* node = attributeSet.Find( name );
1032  if ( !node )
1033  return TIXML_NO_ATTRIBUTE;
1034  *outValue = node->ValueStr();
1035  return TIXML_SUCCESS;
1036  }
1037  */
1038  #endif
1039 
1043  void SetAttribute( const char* name, const char * _value );
1044 
1045  #ifdef TIXML_USE_STL
1046  const std::string* Attribute( const std::string& name ) const;
1047  const std::string* Attribute( const std::string& name, int* i ) const;
1048  const std::string* Attribute( const std::string& name, double* d ) const;
1049  int QueryIntAttribute( const std::string& name, int* _value ) const;
1050  int QueryDoubleAttribute( const std::string& name, double* _value ) const;
1051 
1053  void SetAttribute( const std::string& name, const std::string& _value );
1055  void SetAttribute( const std::string& name, int _value );
1056  #endif
1057 
1061  void SetAttribute( const char * name, int value );
1062 
1066  void SetDoubleAttribute( const char * name, double value );
1067 
1070  void RemoveAttribute( const char * name );
1071  #ifdef TIXML_USE_STL
1072  void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); }
1073  #endif
1074 
1075  const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); }
1076  TiXmlAttribute* FirstAttribute() { return attributeSet.First(); }
1077  const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); }
1078  TiXmlAttribute* LastAttribute() { return attributeSet.Last(); }
1079 
1112  const char* GetText() const;
1113 
1115  virtual TiXmlNode* Clone() const;
1116  // Print the Element to a FILE stream.
1117  virtual void Print( FILE* cfile, int depth ) const;
1118 
1119  /* Attribtue parsing starts: next char past '<'
1120  returns: next char past '>'
1121  */
1122  virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1123 
1124  virtual const TiXmlElement* ToElement() const { return this; }
1125  virtual TiXmlElement* ToElement() { return this; }
1126 
1129  virtual bool Accept( TiXmlVisitor* visitor ) const;
1130 
1131 protected:
1132 
1133  void CopyTo( TiXmlElement* target ) const;
1134  void ClearThis(); // like clear, but initializes 'this' object as well
1135 
1136  // Used to be public [internal use]
1137  #ifdef TIXML_USE_STL
1138  virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1139  #endif
1140  /* [internal use]
1141  Reads the "value" of the element -- another element, or text.
1142  This should terminate with the current end tag.
1143  */
1144  const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1145 
1146 private:
1147 
1148  TiXmlAttributeSet attributeSet;
1149 };
1150 
1151 
1154 class TiXmlComment : public TiXmlNode
1155 {
1156 public:
1158  TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
1160  TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
1161  SetValue( _value );
1162  }
1163  TiXmlComment( const TiXmlComment& );
1164  void operator=( const TiXmlComment& base );
1165 
1166  virtual ~TiXmlComment() {}
1167 
1169  virtual TiXmlNode* Clone() const;
1170  // Write this Comment to a FILE stream.
1171  virtual void Print( FILE* cfile, int depth ) const;
1172 
1173  /* Attribtue parsing starts: at the ! of the !--
1174  returns: next char past '>'
1175  */
1176  virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1177 
1178  virtual const TiXmlComment* ToComment() const { return this; }
1179  virtual TiXmlComment* ToComment() { return this; }
1180 
1183  virtual bool Accept( TiXmlVisitor* visitor ) const;
1184 
1185 protected:
1186  void CopyTo( TiXmlComment* target ) const;
1187 
1188  // used to be public
1189  #ifdef TIXML_USE_STL
1190  virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1191  #endif
1192 // virtual void StreamOut( TIXML_OSTREAM * out ) const;
1193 
1194 private:
1195 
1196 };
1197 
1198 
1204 class TiXmlText : public TiXmlNode
1205 {
1206  friend class TiXmlElement;
1207 public:
1212  TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
1213  {
1214  SetValue( initValue );
1215  cdata = false;
1216  }
1217  virtual ~TiXmlText() {}
1218 
1219  #ifdef TIXML_USE_STL
1220  TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
1222  {
1223  SetValue( initValue );
1224  cdata = false;
1225  }
1226  #endif
1227 
1228  TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); }
1229  void operator=( const TiXmlText& base ) { base.CopyTo( this ); }
1230 
1231  // Write this text object to a FILE stream.
1232  virtual void Print( FILE* cfile, int depth ) const;
1233 
1235  bool CDATA() const { return cdata; }
1237  void SetCDATA( bool _cdata ) { cdata = _cdata; }
1238 
1239  virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1240 
1241  virtual const TiXmlText* ToText() const { return this; }
1242  virtual TiXmlText* ToText() { return this; }
1243 
1246  virtual bool Accept( TiXmlVisitor* content ) const;
1247 
1248 protected :
1250  virtual TiXmlNode* Clone() const;
1251  void CopyTo( TiXmlText* target ) const;
1252 
1253  bool Blank() const; // returns true if all white space and new lines
1254  // [internal use]
1255  #ifdef TIXML_USE_STL
1256  virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1257  #endif
1258 
1259 private:
1260  bool cdata; // true if this should be input and output as a CDATA style text element
1261 };
1262 
1263 
1278 {
1279 public:
1281  TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {}
1282 
1283 #ifdef TIXML_USE_STL
1284  TiXmlDeclaration( const std::string& _version,
1286  const std::string& _encoding,
1287  const std::string& _standalone );
1288 #endif
1289 
1291  TiXmlDeclaration( const char* _version,
1292  const char* _encoding,
1293  const char* _standalone );
1294 
1295  TiXmlDeclaration( const TiXmlDeclaration& copy );
1296  void operator=( const TiXmlDeclaration& copy );
1297 
1298  virtual ~TiXmlDeclaration() {}
1299 
1301  const char *Version() const { return version.c_str (); }
1303  const char *Encoding() const { return encoding.c_str (); }
1305  const char *Standalone() const { return standalone.c_str (); }
1306 
1308  virtual TiXmlNode* Clone() const;
1309  // Print this declaration to a FILE stream.
1310  virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
1311  virtual void Print( FILE* cfile, int depth ) const {
1312  Print( cfile, depth, 0 );
1313  }
1314 
1315  virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1316 
1317  virtual const TiXmlDeclaration* ToDeclaration() const { return this; }
1318  virtual TiXmlDeclaration* ToDeclaration() { return this; }
1319 
1322  virtual bool Accept( TiXmlVisitor* visitor ) const;
1323 
1324 protected:
1325  void CopyTo( TiXmlDeclaration* target ) const;
1326  // used to be public
1327  #ifdef TIXML_USE_STL
1328  virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1329  #endif
1330 
1331 private:
1332 
1333  TIXML_STRING version;
1334  TIXML_STRING encoding;
1335  TIXML_STRING standalone;
1336 };
1337 
1338 
1346 class TiXmlUnknown : public TiXmlNode
1347 {
1348 public:
1349  TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
1350  virtual ~TiXmlUnknown() {}
1351 
1352  TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); }
1353  void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); }
1354 
1356  virtual TiXmlNode* Clone() const;
1357  // Print this Unknown to a FILE stream.
1358  virtual void Print( FILE* cfile, int depth ) const;
1359 
1360  virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1361 
1362  virtual const TiXmlUnknown* ToUnknown() const { return this; }
1363  virtual TiXmlUnknown* ToUnknown() { return this; }
1364 
1367  virtual bool Accept( TiXmlVisitor* content ) const;
1368 
1369 protected:
1370  void CopyTo( TiXmlUnknown* target ) const;
1371 
1372  #ifdef TIXML_USE_STL
1373  virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1374  #endif
1375 
1376 private:
1377 
1378 };
1379 
1380 
1385 class TiXmlDocument : public TiXmlNode
1386 {
1387 public:
1389  TiXmlDocument();
1391  TiXmlDocument( const char * documentName );
1392 
1393  #ifdef TIXML_USE_STL
1394  TiXmlDocument( const std::string& documentName );
1396  #endif
1397 
1398  TiXmlDocument( const TiXmlDocument& copy );
1399  void operator=( const TiXmlDocument& copy );
1400 
1401  virtual ~TiXmlDocument() {}
1402 
1407  bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1409  bool SaveFile() const;
1411  bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1413  bool SaveFile( const char * filename ) const;
1419  bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1421  bool SaveFile( FILE* ) const;
1422 
1423  #ifdef TIXML_USE_STL
1424  bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )
1425  {
1426 // StringToBuffer f( filename );
1427 // return ( f.buffer && LoadFile( f.buffer, encoding ));
1428  return LoadFile( filename.c_str(), encoding );
1429  }
1430  bool SaveFile( const std::string& filename ) const
1431  {
1432 // StringToBuffer f( filename );
1433 // return ( f.buffer && SaveFile( f.buffer ));
1434  return SaveFile( filename.c_str() );
1435  }
1436  #endif
1437 
1442  virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1443 
1448  const TiXmlElement* RootElement() const { return FirstChildElement(); }
1449  TiXmlElement* RootElement() { return FirstChildElement(); }
1450 
1456  bool Error() const { return error; }
1457 
1459  const char * ErrorDesc() const { return errorDesc.c_str (); }
1460 
1464  int ErrorId() const { return errorId; }
1465 
1473  int ErrorRow() const { return errorLocation.row+1; }
1474  int ErrorCol() const { return errorLocation.col+1; }
1475 
1500  void SetTabSize( int _tabsize ) { tabsize = _tabsize; }
1501 
1502  int TabSize() const { return tabsize; }
1503 
1507  void ClearError() { error = false;
1508  errorId = 0;
1509  errorDesc = "";
1510  errorLocation.row = errorLocation.col = 0;
1511  //errorLocation.last = 0;
1512  }
1513 
1515  void Print() const { Print( stdout, 0 ); }
1516 
1517  /* Write the document to a string using formatted printing ("pretty print"). This
1518  will allocate a character array (new char[]) and return it as a pointer. The
1519  calling code pust call delete[] on the return char* to avoid a memory leak.
1520  */
1521  //char* PrintToMemory() const;
1522 
1524  virtual void Print( FILE* cfile, int depth = 0 ) const;
1525  // [internal use]
1526  void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1527 
1528  virtual const TiXmlDocument* ToDocument() const { return this; }
1529  virtual TiXmlDocument* ToDocument() { return this; }
1530 
1533  virtual bool Accept( TiXmlVisitor* content ) const;
1534 
1535 protected :
1536  // [internal use]
1537  virtual TiXmlNode* Clone() const;
1538  #ifdef TIXML_USE_STL
1539  virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1540  #endif
1541 
1542 private:
1543  void CopyTo( TiXmlDocument* target ) const;
1544 
1545  bool error;
1546  int errorId;
1547  TIXML_STRING errorDesc;
1548  int tabsize;
1549  TiXmlCursor errorLocation;
1550  bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write.
1551 };
1552 
1553 
1635 {
1636 public:
1638  TiXmlHandle( TiXmlNode* _node ) { this->node = _node; }
1640  TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; }
1641  TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
1642 
1644  TiXmlHandle FirstChild() const;
1646  TiXmlHandle FirstChild( const char * value ) const;
1650  TiXmlHandle FirstChildElement( const char * value ) const;
1651 
1655  TiXmlHandle Child( const char* value, int index ) const;
1659  TiXmlHandle Child( int index ) const;
1664  TiXmlHandle ChildElement( const char* value, int index ) const;
1669  TiXmlHandle ChildElement( int index ) const;
1670 
1671  #ifdef TIXML_USE_STL
1672  TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); }
1673  TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); }
1674 
1675  TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); }
1676  TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); }
1677  #endif
1678 
1681  TiXmlNode* ToNode() const { return node; }
1684  TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
1687  TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
1690  TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
1691 
1695  TiXmlNode* Node() const { return ToNode(); }
1699  TiXmlElement* Element() const { return ToElement(); }
1703  TiXmlText* Text() const { return ToText(); }
1707  TiXmlUnknown* Unknown() const { return ToUnknown(); }
1708 
1709 private:
1710  TiXmlNode* node;
1711 };
1712 
1713 
1734 {
1735 public:
1736  TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
1737  buffer(), indent( " " ), lineBreak( "\n" ) {}
1738 
1739  virtual bool VisitEnter( const TiXmlDocument& doc );
1740  virtual bool VisitExit( const TiXmlDocument& doc );
1741 
1742  virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
1743  virtual bool VisitExit( const TiXmlElement& element );
1744 
1745  virtual bool Visit( const TiXmlDeclaration& declaration );
1746  virtual bool Visit( const TiXmlText& text );
1747  virtual bool Visit( const TiXmlComment& comment );
1748  virtual bool Visit( const TiXmlUnknown& unknown );
1749 
1753  void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; }
1755  const char* Indent() { return indent.c_str(); }
1760  void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; }
1762  const char* LineBreak() { return lineBreak.c_str(); }
1763 
1767  void SetStreamPrinting() { indent = "";
1768  lineBreak = "";
1769  }
1771  const char* CStr() { return buffer.c_str(); }
1773  size_t Size() { return buffer.size(); }
1774 
1775  #ifdef TIXML_USE_STL
1776  const std::string& Str() { return buffer; }
1778  #endif
1779 
1780 private:
1781  void DoIndent() {
1782  for( int i=0; i<depth; ++i )
1783  buffer += indent;
1784  }
1785  void DoLineBreak() {
1786  buffer += lineBreak;
1787  }
1788 
1789  int depth;
1790  bool simpleTextPrint;
1791  TIXML_STRING buffer;
1792  TIXML_STRING indent;
1793  TIXML_STRING lineBreak;
1794 };
1795 
1796 
1797 #ifdef _MSC_VER
1798 #pragma warning( pop )
1799 #endif
1800 
1801 #endif
1802