Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-27 09:31:27

0001 /*
0002 www.sourceforge.net/projects/tinyxml
0003 Original code by Lee Thomason (www.grinninglizard.com)
0004 
0005 This software is provided 'as-is', without any express or implied
0006 warranty. In no event will the authors be held liable for any
0007 damages arising from the use of this software.
0008 
0009 Permission is granted to anyone to use this software for any
0010 purpose, including commercial applications, and to alter it and
0011 redistribute it freely, subject to the following restrictions:
0012 
0013 1. The origin of this software must not be misrepresented; you must
0014 not claim that you wrote the original software. If you use this
0015 software in a product, an acknowledgment in the product documentation
0016 would be appreciated but is not required.
0017 
0018 2. Altered source versions must be plainly marked as such, and
0019 must not be misrepresented as being the original software.
0020 
0021 3. This notice may not be removed or altered from any source
0022 distribution.
0023 */
0024 
0025 
0026 #ifndef PANDORA_TINYXML_INCLUDED
0027 #define PANDORA_TINYXML_INCLUDED
0028 
0029 #ifndef TIXML_USE_STL // Allowed use of the stl
0030 #define TIXML_USE_STL
0031 #endif
0032 
0033 #ifdef _MSC_VER
0034 #pragma warning( push )
0035 #pragma warning( disable : 4530 )
0036 #pragma warning( disable : 4786 )
0037 #endif
0038 
0039 #include <ctype.h>
0040 #include <stdio.h>
0041 #include <stdlib.h>
0042 #include <string.h>
0043 #include <assert.h>
0044 
0045 // Help out windows:
0046 #if defined( _DEBUG ) && !defined( DEBUG )
0047 #define DEBUG
0048 #endif
0049 
0050 #ifdef TIXML_USE_STL
0051     #include <string>
0052     #include <iostream>
0053     #include <sstream>
0054     #define TIXML_STRING        std::string
0055 #else
0056     #include "tinystr.h"
0057     #define TIXML_STRING        TiXmlString
0058 #endif
0059 
0060 // Deprecated library function hell. Compilers want to use the
0061 // new safe versions. This probably doesn't fully address the problem,
0062 // but it gets closer. There are too many compilers for me to fully
0063 // test. If you get compilation troubles, undefine TIXML_SAFE
0064 #define TIXML_SAFE
0065 
0066 #ifdef TIXML_SAFE
0067     #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
0068         // Microsoft visual studio, version 2005 and higher.
0069         #define TIXML_SNPRINTF _snprintf_s
0070         #define TIXML_SSCANF   sscanf_s
0071     #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
0072         // Microsoft visual studio, version 6 and higher.
0073         //#pragma message( "Using _sn* functions." )
0074         #define TIXML_SNPRINTF _snprintf
0075         #define TIXML_SSCANF   sscanf
0076     #elif defined(__GNUC__) && (__GNUC__ >= 3 )
0077         // GCC version 3 and higher.s
0078         //#warning( "Using sn* functions." )
0079         #define TIXML_SNPRINTF snprintf
0080         #define TIXML_SSCANF   sscanf
0081     #else
0082         #define TIXML_SNPRINTF snprintf
0083         #define TIXML_SSCANF   sscanf
0084     #endif
0085 #endif  
0086 
0087 namespace pandora // Added namespace
0088 {
0089 
0090 class TiXmlDocument;
0091 class TiXmlElement;
0092 class TiXmlComment;
0093 class TiXmlUnknown;
0094 class TiXmlAttribute;
0095 class TiXmlText;
0096 class TiXmlDeclaration;
0097 class TiXmlParsingData;
0098 
0099 const int TIXML_MAJOR_VERSION = 2;
0100 const int TIXML_MINOR_VERSION = 6;
0101 const int TIXML_PATCH_VERSION = 2;
0102 
0103 /*  Internal structure for tracking location of items 
0104     in the XML file.
0105 */
0106 struct TiXmlCursor
0107 {
0108     TiXmlCursor()       { Clear(); }
0109     void Clear()        { row = col = -1; }
0110 
0111     int row;    // 0 based.
0112     int col;    // 0 based.
0113 };
0114 
0115 
0116 /**
0117     Implements the interface to the "Visitor pattern" (see the Accept() method.)
0118     If you call the Accept() method, it requires being passed a TiXmlVisitor
0119     class to handle callbacks. For nodes that contain other nodes (Document, Element)
0120     you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
0121     are simply called with Visit().
0122 
0123     If you return 'true' from a Visit method, recursive parsing will continue. If you return
0124     false, <b>no children of this node or its sibilings</b> will be Visited.
0125 
0126     All flavors of Visit methods have a default implementation that returns 'true' (continue 
0127     visiting). You need to only override methods that are interesting to you.
0128 
0129     Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
0130 
0131     You should never change the document from a callback.
0132 
0133     @sa TiXmlNode::Accept()
0134 */
0135 class TiXmlVisitor
0136 {
0137 public:
0138     virtual ~TiXmlVisitor() {}
0139 
0140     /// Visit a document.
0141     virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )         { return true; }
0142     /// Visit a document.
0143     virtual bool VisitExit( const TiXmlDocument& /*doc*/ )          { return true; }
0144 
0145     /// Visit an element.
0146     virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )    { return true; }
0147     /// Visit an element.
0148     virtual bool VisitExit( const TiXmlElement& /*element*/ )       { return true; }
0149 
0150     /// Visit a declaration
0151     virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )   { return true; }
0152     /// Visit a text node
0153     virtual bool Visit( const TiXmlText& /*text*/ )                 { return true; }
0154     /// Visit a comment node
0155     virtual bool Visit( const TiXmlComment& /*comment*/ )           { return true; }
0156     /// Visit an unknown node
0157     virtual bool Visit( const TiXmlUnknown& /*unknown*/ )           { return true; }
0158 };
0159 
0160 // Only used by Attribute::Query functions
0161 enum 
0162 { 
0163     TIXML_SUCCESS,
0164     TIXML_NO_ATTRIBUTE,
0165     TIXML_WRONG_TYPE
0166 };
0167 
0168 
0169 // Used by the parsing routines.
0170 enum TiXmlEncoding
0171 {
0172     TIXML_ENCODING_UNKNOWN,
0173     TIXML_ENCODING_UTF8,
0174     TIXML_ENCODING_LEGACY
0175 };
0176 
0177 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
0178 
0179 /** TiXmlBase is a base class for every class in TinyXml.
0180     It does little except to establish that TinyXml classes
0181     can be printed and provide some utility functions.
0182 
0183     In XML, the document and elements can contain
0184     other elements and other types of nodes.
0185 
0186     @verbatim
0187     A Document can contain: Element (container or leaf)
0188                             Comment (leaf)
0189                             Unknown (leaf)
0190                             Declaration( leaf )
0191 
0192     An Element can contain: Element (container or leaf)
0193                             Text    (leaf)
0194                             Attributes (not on tree)
0195                             Comment (leaf)
0196                             Unknown (leaf)
0197 
0198     A Decleration contains: Attributes (not on tree)
0199     @endverbatim
0200 */
0201 class TiXmlBase
0202 {
0203     friend class TiXmlNode;
0204     friend class TiXmlElement;
0205     friend class TiXmlDocument;
0206 
0207 public:
0208     TiXmlBase() :   userData(0)     {}
0209     virtual ~TiXmlBase()            {}
0210 
0211     /** All TinyXml classes can print themselves to a filestream
0212         or the string class (TiXmlString in non-STL mode, std::string
0213         in STL mode.) Either or both cfile and str can be null.
0214         
0215         This is a formatted print, and will insert 
0216         tabs and newlines.
0217         
0218         (For an unformatted stream, use the << operator.)
0219     */
0220     virtual void Print( FILE* cfile, int depth ) const = 0;
0221 
0222     /** The world does not agree on whether white space should be kept or
0223         not. In order to make everyone happy, these global, static functions
0224         are provided to set whether or not TinyXml will condense all white space
0225         into a single space or not. The default is to condense. Note changing this
0226         value is not thread safe.
0227     */
0228     static void SetCondenseWhiteSpace( bool condense )      { condenseWhiteSpace = condense; }
0229 
0230     /// Return the current white space setting.
0231     static bool IsWhiteSpaceCondensed()                     { return condenseWhiteSpace; }
0232 
0233     /** Return the position, in the original source file, of this node or attribute.
0234         The row and column are 1-based. (That is the first row and first column is
0235         1,1). If the returns values are 0 or less, then the parser does not have
0236         a row and column value.
0237 
0238         Generally, the row and column value will be set when the TiXmlDocument::Load(),
0239         TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
0240         when the DOM was created from operator>>.
0241 
0242         The values reflect the initial load. Once the DOM is modified programmatically
0243         (by adding or changing nodes and attributes) the new values will NOT update to
0244         reflect changes in the document.
0245 
0246         There is a minor performance cost to computing the row and column. Computation
0247         can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
0248 
0249         @sa TiXmlDocument::SetTabSize()
0250     */
0251     int Row() const         { return location.row + 1; }
0252     int Column() const      { return location.col + 1; }    ///< See Row()
0253 
0254     void  SetUserData( void* user )         { userData = user; }    ///< Set a pointer to arbitrary user data.
0255     void* GetUserData()                     { return userData; }    ///< Get a pointer to arbitrary user data.
0256     const void* GetUserData() const         { return userData; }    ///< Get a pointer to arbitrary user data.
0257 
0258     // Table that returs, for a given lead byte, the total number of bytes
0259     // in the UTF-8 sequence.
0260     static const int utf8ByteTable[256];
0261 
0262     virtual const char* Parse(  const char* p, 
0263                                 TiXmlParsingData* data, 
0264                                 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
0265 
0266     /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, 
0267         or they will be transformed into entities!
0268     */
0269     static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
0270 
0271     enum
0272     {
0273         TIXML_NO_ERROR = 0,
0274         TIXML_ERROR,
0275         TIXML_ERROR_OPENING_FILE,
0276         TIXML_ERROR_PARSING_ELEMENT,
0277         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
0278         TIXML_ERROR_READING_ELEMENT_VALUE,
0279         TIXML_ERROR_READING_ATTRIBUTES,
0280         TIXML_ERROR_PARSING_EMPTY,
0281         TIXML_ERROR_READING_END_TAG,
0282         TIXML_ERROR_PARSING_UNKNOWN,
0283         TIXML_ERROR_PARSING_COMMENT,
0284         TIXML_ERROR_PARSING_DECLARATION,
0285         TIXML_ERROR_DOCUMENT_EMPTY,
0286         TIXML_ERROR_EMBEDDED_NULL,
0287         TIXML_ERROR_PARSING_CDATA,
0288         TIXML_ERROR_DOCUMENT_TOP_ONLY,
0289 
0290         TIXML_ERROR_STRING_COUNT
0291     };
0292 
0293 protected:
0294 
0295     static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
0296 
0297     inline static bool IsWhiteSpace( char c )       
0298     { 
0299         return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
0300     }
0301     inline static bool IsWhiteSpace( int c )
0302     {
0303         if ( c < 256 )
0304             return IsWhiteSpace( (char) c );
0305         return false;   // Again, only truly correct for English/Latin...but usually works.
0306     }
0307 
0308     #ifdef TIXML_USE_STL
0309     static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
0310     static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
0311     #endif
0312 
0313     /*  Reads an XML name into the string provided. Returns
0314         a pointer just past the last character of the name,
0315         or 0 if the function has an error.
0316     */
0317     static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
0318 
0319     /*  Reads text. Returns a pointer past the given end tag.
0320         Wickedly complex options, but it keeps the (sensitive) code in one place.
0321     */
0322     static const char* ReadText(    const char* in,             // where to start
0323                                     TIXML_STRING* text,         // the string read
0324                                     bool ignoreWhiteSpace,      // whether to keep the white space
0325                                     const char* endTag,         // what ends this text
0326                                     bool ignoreCase,            // whether to ignore case in the end tag
0327                                     TiXmlEncoding encoding );   // the current encoding
0328 
0329     // If an entity has been found, transform it into a character.
0330     static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
0331 
0332     // Get a character, while interpreting entities.
0333     // The length can be from 0 to 4 bytes.
0334     inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
0335     {
0336         assert( p );
0337         if ( encoding == TIXML_ENCODING_UTF8 )
0338         {
0339             *length = utf8ByteTable[ *((const unsigned char*)p) ];
0340             assert( *length >= 0 && *length < 5 );
0341         }
0342         else
0343         {
0344             *length = 1;
0345         }
0346 
0347         if ( *length == 1 )
0348         {
0349             if ( *p == '&' )
0350                 return GetEntity( p, _value, length, encoding );
0351             *_value = *p;
0352             return p+1;
0353         }
0354         else if ( *length )
0355         {
0356             //strncpy( _value, p, *length );    // lots of compilers don't like this function (unsafe),
0357                                                 // and the null terminator isn't needed
0358             for( int i=0; p[i] && i<*length; ++i ) {
0359                 _value[i] = p[i];
0360             }
0361             return p + (*length);
0362         }
0363         else
0364         {
0365             // Not valid text.
0366             return 0;
0367         }
0368     }
0369 
0370     // Return true if the next characters in the stream are any of the endTag sequences.
0371     // Ignore case only works for english, and should only be relied on when comparing
0372     // to English words: StringEqual( p, "version", true ) is fine.
0373     static bool StringEqual(    const char* p,
0374                                 const char* endTag,
0375                                 bool ignoreCase,
0376                                 TiXmlEncoding encoding );
0377 
0378     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
0379 
0380     TiXmlCursor location;
0381 
0382     /// Field containing a generic user pointer
0383     void*           userData;
0384     
0385     // None of these methods are reliable for any language except English.
0386     // Good for approximation, not great for accuracy.
0387     static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
0388     static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
0389     inline static int ToLower( int v, TiXmlEncoding encoding )
0390     {
0391         if ( encoding == TIXML_ENCODING_UTF8 )
0392         {
0393             if ( v < 128 ) return tolower( v );
0394             return v;
0395         }
0396         else
0397         {
0398             return tolower( v );
0399         }
0400     }
0401     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
0402 
0403 private:
0404     TiXmlBase( const TiXmlBase& );              // not implemented.
0405     void operator=( const TiXmlBase& base );    // not allowed.
0406 
0407     struct Entity
0408     {
0409         const char*     str;
0410         unsigned int    strLength;
0411         char            chr;
0412     };
0413     enum
0414     {
0415         NUM_ENTITY = 5,
0416         MAX_ENTITY_LENGTH = 6
0417 
0418     };
0419     static Entity entity[ NUM_ENTITY ];
0420     static bool condenseWhiteSpace;
0421 };
0422 
0423 
0424 /** The parent class for everything in the Document Object Model.
0425     (Except for attributes).
0426     Nodes have siblings, a parent, and children. A node can be
0427     in a document, or stand on its own. The type of a TiXmlNode
0428     can be queried, and it can be cast to its more defined type.
0429 */
0430 class TiXmlNode : public TiXmlBase
0431 {
0432     friend class TiXmlDocument;
0433     friend class TiXmlElement;
0434 
0435 public:
0436     #ifdef TIXML_USE_STL    
0437 
0438         /** An input stream operator, for every class. Tolerant of newlines and
0439             formatting, but doesn't expect them.
0440         */
0441         friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
0442 
0443         /** An output stream operator, for every class. Note that this outputs
0444             without any newlines or formatting, as opposed to Print(), which
0445             includes tabs and new lines.
0446 
0447             The operator<< and operator>> are not completely symmetric. Writing
0448             a node to a stream is very well defined. You'll get a nice stream
0449             of output, without any extra whitespace or newlines.
0450             
0451             But reading is not as well defined. (As it always is.) If you create
0452             a TiXmlElement (for example) and read that from an input stream,
0453             the text needs to define an element or junk will result. This is
0454             true of all input streams, but it's worth keeping in mind.
0455 
0456             A TiXmlDocument will read nodes until it reads a root element, and
0457             all the children of that root element.
0458         */  
0459         friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
0460 
0461         /// Appends the XML node or attribute to a std::string.
0462         friend std::string& operator<< (std::string& out, const TiXmlNode& base );
0463 
0464     #endif
0465 
0466     /** The types of XML nodes supported by TinyXml. (All the
0467             unsupported types are picked up by UNKNOWN.)
0468     */
0469     enum NodeType
0470     {
0471         TINYXML_DOCUMENT,
0472         TINYXML_ELEMENT,
0473         TINYXML_COMMENT,
0474         TINYXML_UNKNOWN,
0475         TINYXML_TEXT,
0476         TINYXML_DECLARATION,
0477         TINYXML_TYPECOUNT
0478     };
0479 
0480     virtual ~TiXmlNode();
0481 
0482     /** The meaning of 'value' changes for the specific type of
0483         TiXmlNode.
0484         @verbatim
0485         Document:   filename of the xml file
0486         Element:    name of the element
0487         Comment:    the comment text
0488         Unknown:    the tag contents
0489         Text:       the text string
0490         @endverbatim
0491 
0492         The subclasses will wrap this function.
0493     */
0494     const char *Value() const { return value.c_str (); }
0495 
0496     #ifdef TIXML_USE_STL
0497     /** Return Value() as a std::string. If you only use STL,
0498         this is more efficient than calling Value().
0499         Only available in STL mode.
0500     */
0501     const std::string& ValueStr() const { return value; }
0502     #endif
0503 
0504     const TIXML_STRING& ValueTStr() const { return value; }
0505 
0506     /** Changes the value of the node. Defined as:
0507         @verbatim
0508         Document:   filename of the xml file
0509         Element:    name of the element
0510         Comment:    the comment text
0511         Unknown:    the tag contents
0512         Text:       the text string
0513         @endverbatim
0514     */
0515     void SetValue(const char * _value) { value = _value;}
0516 
0517     #ifdef TIXML_USE_STL
0518     /// STL std::string form.
0519     void SetValue( const std::string& _value )  { value = _value; }
0520     #endif
0521 
0522     /// Delete all the children of this node. Does not affect 'this'.
0523     void Clear();
0524 
0525     /// One step up the DOM.
0526     TiXmlNode* Parent()                         { return parent; }
0527     const TiXmlNode* Parent() const             { return parent; }
0528 
0529     const TiXmlNode* FirstChild()   const       { return firstChild; }  ///< The first child of this node. Will be null if there are no children.
0530     TiXmlNode* FirstChild()                     { return firstChild; }
0531     const TiXmlNode* FirstChild( const char * value ) const;            ///< The first child of this node with the matching 'value'. Will be null if none found.
0532     /// The first child of this node with the matching 'value'. Will be null if none found.
0533     TiXmlNode* FirstChild( const char * _value ) {
0534         // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
0535         // call the method, cast the return back to non-const.
0536         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
0537     }
0538     const TiXmlNode* LastChild() const  { return lastChild; }       /// The last child of this node. Will be null if there are no children.
0539     TiXmlNode* LastChild()  { return lastChild; }
0540     
0541     const TiXmlNode* LastChild( const char * value ) const;         /// The last child of this node matching 'value'. Will be null if there are no children.
0542     TiXmlNode* LastChild( const char * _value ) {
0543         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
0544     }
0545 
0546     #ifdef TIXML_USE_STL
0547     const TiXmlNode* FirstChild( const std::string& _value ) const  {   return FirstChild (_value.c_str ());    }   ///< STL std::string form.
0548     TiXmlNode* FirstChild( const std::string& _value )              {   return FirstChild (_value.c_str ());    }   ///< STL std::string form.
0549     const TiXmlNode* LastChild( const std::string& _value ) const   {   return LastChild (_value.c_str ()); }   ///< STL std::string form.
0550     TiXmlNode* LastChild( const std::string& _value )               {   return LastChild (_value.c_str ()); }   ///< STL std::string form.
0551     #endif
0552 
0553     /** An alternate way to walk the children of a node.
0554         One way to iterate over nodes is:
0555         @verbatim
0556             for( child = parent->FirstChild(); child; child = child->NextSibling() )
0557         @endverbatim
0558 
0559         IterateChildren does the same thing with the syntax:
0560         @verbatim
0561             child = 0;
0562             while( child = parent->IterateChildren( child ) )
0563         @endverbatim
0564 
0565         IterateChildren takes the previous child as input and finds
0566         the next one. If the previous child is null, it returns the
0567         first. IterateChildren will return null when done.
0568     */
0569     const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
0570     TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
0571         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
0572     }
0573 
0574     /// This flavor of IterateChildren searches for children with a particular 'value'
0575     const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
0576     TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
0577         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
0578     }
0579 
0580     #ifdef TIXML_USE_STL
0581     const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const  {   return IterateChildren (_value.c_str (), previous); }   ///< STL std::string form.
0582     TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {    return IterateChildren (_value.c_str (), previous); }   ///< STL std::string form.
0583     #endif
0584 
0585     /** Add a new node related to this. Adds a child past the LastChild.
0586         Returns a pointer to the new object or NULL if an error occured.
0587     */
0588     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
0589 
0590 
0591     /** Add a new node related to this. Adds a child past the LastChild.
0592 
0593         NOTE: the node to be added is passed by pointer, and will be
0594         henceforth owned (and deleted) by tinyXml. This method is efficient
0595         and avoids an extra copy, but should be used with care as it
0596         uses a different memory model than the other insert functions.
0597 
0598         @sa InsertEndChild
0599     */
0600     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
0601 
0602     /** Add a new node related to this. Adds a child before the specified child.
0603         Returns a pointer to the new object or NULL if an error occured.
0604     */
0605     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
0606 
0607     /** Add a new node related to this. Adds a child after the specified child.
0608         Returns a pointer to the new object or NULL if an error occured.
0609     */
0610     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
0611 
0612     /** Replace a child of this node.
0613         Returns a pointer to the new object or NULL if an error occured.
0614     */
0615     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
0616 
0617     /// Delete a child of this node.
0618     bool RemoveChild( TiXmlNode* removeThis );
0619 
0620     /// Navigate to a sibling node.
0621     const TiXmlNode* PreviousSibling() const            { return prev; }
0622     TiXmlNode* PreviousSibling()                        { return prev; }
0623 
0624     /// Navigate to a sibling node.
0625     const TiXmlNode* PreviousSibling( const char * ) const;
0626     TiXmlNode* PreviousSibling( const char *_prev ) {
0627         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
0628     }
0629 
0630     #ifdef TIXML_USE_STL
0631     const TiXmlNode* PreviousSibling( const std::string& _value ) const {   return PreviousSibling (_value.c_str ());   }   ///< STL std::string form.
0632     TiXmlNode* PreviousSibling( const std::string& _value )             {   return PreviousSibling (_value.c_str ());   }   ///< STL std::string form.
0633     const TiXmlNode* NextSibling( const std::string& _value) const      {   return NextSibling (_value.c_str ());   }   ///< STL std::string form.
0634     TiXmlNode* NextSibling( const std::string& _value)                  {   return NextSibling (_value.c_str ());   }   ///< STL std::string form.
0635     #endif
0636 
0637     /// Navigate to a sibling node.
0638     const TiXmlNode* NextSibling() const                { return next; }
0639     TiXmlNode* NextSibling()                            { return next; }
0640 
0641     /// Navigate to a sibling node with the given 'value'.
0642     const TiXmlNode* NextSibling( const char * ) const;
0643     TiXmlNode* NextSibling( const char* _next ) {
0644         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
0645     }
0646 
0647     /** Convenience function to get through elements.
0648         Calls NextSibling and ToElement. Will skip all non-Element
0649         nodes. Returns 0 if there is not another element.
0650     */
0651     const TiXmlElement* NextSiblingElement() const;
0652     TiXmlElement* NextSiblingElement() {
0653         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
0654     }
0655 
0656     /** Convenience function to get through elements.
0657         Calls NextSibling and ToElement. Will skip all non-Element
0658         nodes. Returns 0 if there is not another element.
0659     */
0660     const TiXmlElement* NextSiblingElement( const char * ) const;
0661     TiXmlElement* NextSiblingElement( const char *_next ) {
0662         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
0663     }
0664 
0665     #ifdef TIXML_USE_STL
0666     const TiXmlElement* NextSiblingElement( const std::string& _value) const    {   return NextSiblingElement (_value.c_str ());    }   ///< STL std::string form.
0667     TiXmlElement* NextSiblingElement( const std::string& _value)                {   return NextSiblingElement (_value.c_str ());    }   ///< STL std::string form.
0668     #endif
0669 
0670     /// Convenience function to get through elements.
0671     const TiXmlElement* FirstChildElement() const;
0672     TiXmlElement* FirstChildElement() {
0673         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
0674     }
0675 
0676     /// Convenience function to get through elements.
0677     const TiXmlElement* FirstChildElement( const char * _value ) const;
0678     TiXmlElement* FirstChildElement( const char * _value ) {
0679         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
0680     }
0681 
0682     #ifdef TIXML_USE_STL
0683     const TiXmlElement* FirstChildElement( const std::string& _value ) const    {   return FirstChildElement (_value.c_str ()); }   ///< STL std::string form.
0684     TiXmlElement* FirstChildElement( const std::string& _value )                {   return FirstChildElement (_value.c_str ()); }   ///< STL std::string form.
0685     #endif
0686 
0687     /** Query the type (as an enumerated value, above) of this node.
0688         The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT,
0689                                 TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION.
0690     */
0691     int Type() const    { return type; }
0692 
0693     /** Return a pointer to the Document this node lives in.
0694         Returns null if not in a document.
0695     */
0696     const TiXmlDocument* GetDocument() const;
0697     TiXmlDocument* GetDocument() {
0698         return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
0699     }
0700 
0701     /// Returns true if this node has no children.
0702     bool NoChildren() const                     { return !firstChild; }
0703 
0704     virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0705     virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0706     virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0707     virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0708     virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0709     virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0710 
0711     virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0712     virtual TiXmlElement*           ToElement()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0713     virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0714     virtual TiXmlUnknown*           ToUnknown()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0715     virtual TiXmlText*              ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0716     virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
0717 
0718     /** Create an exact duplicate of this node and return it. The memory must be deleted
0719         by the caller. 
0720     */
0721     virtual TiXmlNode* Clone() const = 0;
0722 
0723     /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the 
0724         XML tree will be conditionally visited and the host will be called back
0725         via the TiXmlVisitor interface.
0726 
0727         This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
0728         the XML for the callbacks, so the performance of TinyXML is unchanged by using this
0729         interface versus any other.)
0730 
0731         The interface has been based on ideas from:
0732 
0733         - http://www.saxproject.org/
0734         - http://c2.com/cgi/wiki?HierarchicalVisitorPattern 
0735 
0736         Which are both good references for "visiting".
0737 
0738         An example of using Accept():
0739         @verbatim
0740         TiXmlPrinter printer;
0741         tinyxmlDoc.Accept( &printer );
0742         const char* xmlcstr = printer.CStr();
0743         @endverbatim
0744     */
0745     virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
0746 
0747 protected:
0748     TiXmlNode( NodeType _type );
0749 
0750     // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
0751     // and the assignment operator.
0752     void CopyTo( TiXmlNode* target ) const;
0753 
0754     #ifdef TIXML_USE_STL
0755         // The real work of the input operator.
0756     virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
0757     #endif
0758 
0759     // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
0760     TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
0761 
0762     TiXmlNode*      parent;
0763     NodeType        type;
0764 
0765     TiXmlNode*      firstChild;
0766     TiXmlNode*      lastChild;
0767 
0768     TIXML_STRING    value;
0769 
0770     TiXmlNode*      prev;
0771     TiXmlNode*      next;
0772 
0773 private:
0774     TiXmlNode( const TiXmlNode& );              // not implemented.
0775     void operator=( const TiXmlNode& base );    // not allowed.
0776 };
0777 
0778 
0779 /** An attribute is a name-value pair. Elements have an arbitrary
0780     number of attributes, each with a unique name.
0781 
0782     @note The attributes are not TiXmlNodes, since they are not
0783           part of the tinyXML document object model. There are other
0784           suggested ways to look at this problem.
0785 */
0786 class TiXmlAttribute : public TiXmlBase
0787 {
0788     friend class TiXmlAttributeSet;
0789 
0790 public:
0791     /// Construct an empty attribute.
0792     TiXmlAttribute() : TiXmlBase()
0793     {
0794         document = 0;
0795         prev = next = 0;
0796     }
0797 
0798     #ifdef TIXML_USE_STL
0799     /// std::string constructor.
0800     TiXmlAttribute( const std::string& _name, const std::string& _value )
0801     {
0802         name = _name;
0803         value = _value;
0804         document = 0;
0805         prev = next = 0;
0806     }
0807     #endif
0808 
0809     /// Construct an attribute with a name and value.
0810     TiXmlAttribute( const char * _name, const char * _value )
0811     {
0812         name = _name;
0813         value = _value;
0814         document = 0;
0815         prev = next = 0;
0816     }
0817 
0818     const char*     Name()  const       { return name.c_str(); }        ///< Return the name of this attribute.
0819     const char*     Value() const       { return value.c_str(); }       ///< Return the value of this attribute.
0820     #ifdef TIXML_USE_STL
0821     const std::string& ValueStr() const { return value; }               ///< Return the value of this attribute.
0822     #endif
0823     int             IntValue() const;                                   ///< Return the value of this attribute, converted to an integer.
0824     double          DoubleValue() const;                                ///< Return the value of this attribute, converted to a double.
0825 
0826     // Get the tinyxml string representation
0827     const TIXML_STRING& NameTStr() const { return name; }
0828 
0829     /** QueryIntValue examines the value string. It is an alternative to the
0830         IntValue() method with richer error checking.
0831         If the value is an integer, it is stored in 'value' and 
0832         the call returns TIXML_SUCCESS. If it is not
0833         an integer, it returns TIXML_WRONG_TYPE.
0834 
0835         A specialized but useful call. Note that for success it returns 0,
0836         which is the opposite of almost all other TinyXml calls.
0837     */
0838     int QueryIntValue( int* _value ) const;
0839     /// QueryDoubleValue examines the value string. See QueryIntValue().
0840     int QueryDoubleValue( double* _value ) const;
0841 
0842     void SetName( const char* _name )   { name = _name; }               ///< Set the name of this attribute.
0843     void SetValue( const char* _value ) { value = _value; }             ///< Set the value.
0844 
0845     void SetIntValue( int _value );                                     ///< Set the value from an integer.
0846     void SetDoubleValue( double _value );                               ///< Set the value from a double.
0847 
0848     #ifdef TIXML_USE_STL
0849     /// STL std::string form.
0850     void SetName( const std::string& _name )    { name = _name; }   
0851     /// STL std::string form.   
0852     void SetValue( const std::string& _value )  { value = _value; }
0853     #endif
0854 
0855     /// Get the next sibling attribute in the DOM. Returns null at end.
0856     const TiXmlAttribute* Next() const;
0857     TiXmlAttribute* Next() {
0858         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
0859     }
0860 
0861     /// Get the previous sibling attribute in the DOM. Returns null at beginning.
0862     const TiXmlAttribute* Previous() const;
0863     TiXmlAttribute* Previous() {
0864         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
0865     }
0866 
0867     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
0868     bool operator<( const TiXmlAttribute& rhs )  const { return name < rhs.name; }
0869     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
0870 
0871     /*  Attribute parsing starts: first letter of the name
0872                          returns: the next char after the value end quote
0873     */
0874     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
0875 
0876     // Prints this Attribute to a FILE stream.
0877     virtual void Print( FILE* cfile, int depth ) const {
0878         Print( cfile, depth, 0 );
0879     }
0880     void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
0881 
0882     // [internal use]
0883     // Set the document pointer so the attribute can report errors.
0884     void SetDocument( TiXmlDocument* doc )  { document = doc; }
0885 
0886 private:
0887     TiXmlAttribute( const TiXmlAttribute& );                // not implemented.
0888     void operator=( const TiXmlAttribute& base );   // not allowed.
0889 
0890     TiXmlDocument*  document;   // A pointer back to a document, for error reporting.
0891     TIXML_STRING name;
0892     TIXML_STRING value;
0893     TiXmlAttribute* prev;
0894     TiXmlAttribute* next;
0895 };
0896 
0897 
0898 /*  A class used to manage a group of attributes.
0899     It is only used internally, both by the ELEMENT and the DECLARATION.
0900     
0901     The set can be changed transparent to the Element and Declaration
0902     classes that use it, but NOT transparent to the Attribute
0903     which has to implement a next() and previous() method. Which makes
0904     it a bit problematic and prevents the use of STL.
0905 
0906     This version is implemented with circular lists because:
0907         - I like circular lists
0908         - it demonstrates some independence from the (typical) doubly linked list.
0909 */
0910 class TiXmlAttributeSet
0911 {
0912 public:
0913     TiXmlAttributeSet();
0914     ~TiXmlAttributeSet();
0915 
0916     void Add( TiXmlAttribute* attribute );
0917     void Remove( TiXmlAttribute* attribute );
0918 
0919     const TiXmlAttribute* First()   const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
0920     TiXmlAttribute* First()                 { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
0921     const TiXmlAttribute* Last() const      { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
0922     TiXmlAttribute* Last()                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
0923 
0924     TiXmlAttribute* Find( const char* _name ) const;
0925     TiXmlAttribute* FindOrCreate( const char* _name );
0926 
0927 #   ifdef TIXML_USE_STL
0928     TiXmlAttribute* Find( const std::string& _name ) const;
0929     TiXmlAttribute* FindOrCreate( const std::string& _name );
0930 #   endif
0931 
0932 
0933 private:
0934     //*ME:  Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
0935     //*ME:  this class must be also use a hidden/disabled copy-constructor !!!
0936     TiXmlAttributeSet( const TiXmlAttributeSet& );  // not allowed
0937     void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
0938 
0939     TiXmlAttribute sentinel;
0940 };
0941 
0942 
0943 /** The element is a container class. It has a value, the element name,
0944     and can contain other elements, text, comments, and unknowns.
0945     Elements also contain an arbitrary number of attributes.
0946 */
0947 class TiXmlElement : public TiXmlNode
0948 {
0949 public:
0950     /// Construct an element.
0951     TiXmlElement (const char * in_value);
0952 
0953     #ifdef TIXML_USE_STL
0954     /// std::string constructor.
0955     TiXmlElement( const std::string& _value );
0956     #endif
0957 
0958     TiXmlElement( const TiXmlElement& );
0959 
0960     TiXmlElement& operator=( const TiXmlElement& base );
0961 
0962     virtual ~TiXmlElement();
0963 
0964     /** Given an attribute name, Attribute() returns the value
0965         for the attribute of that name, or null if none exists.
0966     */
0967     const char* Attribute( const char* name ) const;
0968 
0969     /** Given an attribute name, Attribute() returns the value
0970         for the attribute of that name, or null if none exists.
0971         If the attribute exists and can be converted to an integer,
0972         the integer value will be put in the return 'i', if 'i'
0973         is non-null.
0974     */
0975     const char* Attribute( const char* name, int* i ) const;
0976 
0977     /** Given an attribute name, Attribute() returns the value
0978         for the attribute of that name, or null if none exists.
0979         If the attribute exists and can be converted to an double,
0980         the double value will be put in the return 'd', if 'd'
0981         is non-null.
0982     */
0983     const char* Attribute( const char* name, double* d ) const;
0984 
0985     /** QueryIntAttribute examines the attribute - it is an alternative to the
0986         Attribute() method with richer error checking.
0987         If the attribute is an integer, it is stored in 'value' and 
0988         the call returns TIXML_SUCCESS. If it is not
0989         an integer, it returns TIXML_WRONG_TYPE. If the attribute
0990         does not exist, then TIXML_NO_ATTRIBUTE is returned.
0991     */  
0992     int QueryIntAttribute( const char* name, int* _value ) const;
0993     /// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().
0994     int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;
0995     /** QueryBoolAttribute examines the attribute - see QueryIntAttribute(). 
0996         Note that '1', 'true', or 'yes' are considered true, while '0', 'false'
0997         and 'no' are considered false.
0998     */
0999     int QueryBoolAttribute( const char* name, bool* _value ) const;
1000     /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
1001     int QueryDoubleAttribute( const char* name, double* _value ) const;
1002     /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
1003     int QueryFloatAttribute( const char* name, float* _value ) const {
1004         double d;
1005         int result = QueryDoubleAttribute( name, &d );
1006         if ( result == TIXML_SUCCESS ) {
1007             *_value = (float)d;
1008         }
1009         return result;
1010     }
1011 
1012     #ifdef TIXML_USE_STL
1013     /// QueryStringAttribute examines the attribute - see QueryIntAttribute().
1014     int QueryStringAttribute( const char* name, std::string* _value ) const {
1015         const char* cstr = Attribute( name );
1016         if ( cstr ) {
1017             *_value = std::string( cstr );
1018             return TIXML_SUCCESS;
1019         }
1020         return TIXML_NO_ATTRIBUTE;
1021     }
1022 
1023     /** Template form of the attribute query which will try to read the
1024         attribute into the specified type. Very easy, very powerful, but
1025         be careful to make sure to call this with the correct type.
1026         
1027         NOTE: This method doesn't work correctly for 'string' types that contain spaces.
1028 
1029         @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
1030     */
1031     template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
1032     {
1033         const TiXmlAttribute* node = attributeSet.Find( name );
1034         if ( !node )
1035             return TIXML_NO_ATTRIBUTE;
1036 
1037         std::stringstream sstream( node->ValueStr() );
1038         sstream >> *outValue;
1039         if ( !sstream.fail() )
1040             return TIXML_SUCCESS;
1041         return TIXML_WRONG_TYPE;
1042     }
1043 
1044     int QueryValueAttribute( const std::string& name, std::string* outValue ) const
1045     {
1046         const TiXmlAttribute* node = attributeSet.Find( name );
1047         if ( !node )
1048             return TIXML_NO_ATTRIBUTE;
1049         *outValue = node->ValueStr();
1050         return TIXML_SUCCESS;
1051     }
1052     #endif
1053 
1054     /** Sets an attribute of name to a given value. The attribute
1055         will be created if it does not exist, or changed if it does.
1056     */
1057     void SetAttribute( const char* name, const char * _value );
1058 
1059     #ifdef TIXML_USE_STL
1060     const std::string* Attribute( const std::string& name ) const;
1061     const std::string* Attribute( const std::string& name, int* i ) const;
1062     const std::string* Attribute( const std::string& name, double* d ) const;
1063     int QueryIntAttribute( const std::string& name, int* _value ) const;
1064     int QueryDoubleAttribute( const std::string& name, double* _value ) const;
1065 
1066     /// STL std::string form.
1067     void SetAttribute( const std::string& name, const std::string& _value );
1068     ///< STL std::string form.
1069     void SetAttribute( const std::string& name, int _value );
1070     ///< STL std::string form.
1071     void SetDoubleAttribute( const std::string& name, double value );
1072     #endif
1073 
1074     /** Sets an attribute of name to a given value. The attribute
1075         will be created if it does not exist, or changed if it does.
1076     */
1077     void SetAttribute( const char * name, int value );
1078 
1079     /** Sets an attribute of name to a given value. The attribute
1080         will be created if it does not exist, or changed if it does.
1081     */
1082     void SetDoubleAttribute( const char * name, double value );
1083 
1084     /** Deletes an attribute with the given name.
1085     */
1086     void RemoveAttribute( const char * name );
1087     #ifdef TIXML_USE_STL
1088     void RemoveAttribute( const std::string& name ) {   RemoveAttribute (name.c_str ());    }   ///< STL std::string form.
1089     #endif
1090 
1091     const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }        ///< Access the first attribute in this element.
1092     TiXmlAttribute* FirstAttribute()                { return attributeSet.First(); }
1093     const TiXmlAttribute* LastAttribute()   const   { return attributeSet.Last(); }     ///< Access the last attribute in this element.
1094     TiXmlAttribute* LastAttribute()                 { return attributeSet.Last(); }
1095 
1096     /** Convenience function for easy access to the text inside an element. Although easy
1097         and concise, GetText() is limited compared to getting the TiXmlText child
1098         and accessing it directly.
1099     
1100         If the first child of 'this' is a TiXmlText, the GetText()
1101         returns the character string of the Text node, else null is returned.
1102 
1103         This is a convenient method for getting the text of simple contained text:
1104         @verbatim
1105         <foo>This is text</foo>
1106         const char* str = fooElement->GetText();
1107         @endverbatim
1108 
1109         'str' will be a pointer to "This is text". 
1110         
1111         Note that this function can be misleading. If the element foo was created from
1112         this XML:
1113         @verbatim
1114         <foo><b>This is text</b></foo> 
1115         @endverbatim
1116 
1117         then the value of str would be null. The first child node isn't a text node, it is
1118         another element. From this XML:
1119         @verbatim
1120         <foo>This is <b>text</b></foo> 
1121         @endverbatim
1122         GetText() will return "This is ".
1123 
1124         WARNING: GetText() accesses a child node - don't become confused with the 
1125                  similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
1126                  safe type casts on the referenced node.
1127     */
1128     const char* GetText() const;
1129 
1130     /// Creates a new Element and returns it - the returned element is a copy.
1131     virtual TiXmlNode* Clone() const;
1132     // Print the Element to a FILE stream.
1133     virtual void Print( FILE* cfile, int depth ) const;
1134 
1135     /*  Attribtue parsing starts: next char past '<'
1136                          returns: next char past '>'
1137     */
1138     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1139 
1140     virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1141     virtual TiXmlElement*           ToElement()           { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1142 
1143     /** Walk the XML tree visiting this node and all of its children. 
1144     */
1145     virtual bool Accept( TiXmlVisitor* visitor ) const;
1146 
1147 protected:
1148 
1149     void CopyTo( TiXmlElement* target ) const;
1150     void ClearThis();   // like clear, but initializes 'this' object as well
1151 
1152     // Used to be public [internal use]
1153     #ifdef TIXML_USE_STL
1154     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1155     #endif
1156     /*  [internal use]
1157         Reads the "value" of the element -- another element, or text.
1158         This should terminate with the current end tag.
1159     */
1160     const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1161 
1162 private:
1163     TiXmlAttributeSet attributeSet;
1164 };
1165 
1166 
1167 /** An XML comment.
1168 */
1169 class TiXmlComment : public TiXmlNode
1170 {
1171 public:
1172     /// Constructs an empty comment.
1173     TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
1174     /// Construct a comment from text.
1175     TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
1176         SetValue( _value );
1177     }
1178     TiXmlComment( const TiXmlComment& );
1179     TiXmlComment& operator=( const TiXmlComment& base );
1180 
1181     virtual ~TiXmlComment() {}
1182 
1183     /// Returns a copy of this Comment.
1184     virtual TiXmlNode* Clone() const;
1185     // Write this Comment to a FILE stream.
1186     virtual void Print( FILE* cfile, int depth ) const;
1187 
1188     /*  Attribtue parsing starts: at the ! of the !--
1189                          returns: next char past '>'
1190     */
1191     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1192 
1193     virtual const TiXmlComment*  ToComment() const  { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1194     virtual       TiXmlComment*  ToComment()        { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1195 
1196     /** Walk the XML tree visiting this node and all of its children. 
1197     */
1198     virtual bool Accept( TiXmlVisitor* visitor ) const;
1199 
1200 protected:
1201     void CopyTo( TiXmlComment* target ) const;
1202 
1203     // used to be public
1204     #ifdef TIXML_USE_STL
1205     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1206     #endif
1207 //  virtual void StreamOut( TIXML_OSTREAM * out ) const;
1208 
1209 private:
1210 
1211 };
1212 
1213 
1214 /** XML text. A text node can have 2 ways to output the next. "normal" output 
1215     and CDATA. It will default to the mode it was parsed from the XML file and
1216     you generally want to leave it alone, but you can change the output mode with 
1217     SetCDATA() and query it with CDATA().
1218 */
1219 class TiXmlText : public TiXmlNode
1220 {
1221     friend class TiXmlElement;
1222 public:
1223     /** Constructor for text element. By default, it is treated as 
1224         normal, encoded text. If you want it be output as a CDATA text
1225         element, set the parameter _cdata to 'true'
1226     */
1227     TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
1228     {
1229         SetValue( initValue );
1230         cdata = false;
1231     }
1232     virtual ~TiXmlText() {}
1233 
1234     #ifdef TIXML_USE_STL
1235     /// Constructor.
1236     TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
1237     {
1238         SetValue( initValue );
1239         cdata = false;
1240     }
1241     #endif
1242 
1243     TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT )   { copy.CopyTo( this ); }
1244     TiXmlText& operator=( const TiXmlText& base )                               { base.CopyTo( this ); return *this; }
1245 
1246     // Write this text object to a FILE stream.
1247     virtual void Print( FILE* cfile, int depth ) const;
1248 
1249     /// Queries whether this represents text using a CDATA section.
1250     bool CDATA() const              { return cdata; }
1251     /// Turns on or off a CDATA representation of text.
1252     void SetCDATA( bool _cdata )    { cdata = _cdata; }
1253 
1254     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1255 
1256     virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1257     virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1258 
1259     /** Walk the XML tree visiting this node and all of its children. 
1260     */
1261     virtual bool Accept( TiXmlVisitor* content ) const;
1262 
1263 protected :
1264     ///  [internal use] Creates a new Element and returns it.
1265     virtual TiXmlNode* Clone() const;
1266     void CopyTo( TiXmlText* target ) const;
1267 
1268     bool Blank() const; // returns true if all white space and new lines
1269     // [internal use]
1270     #ifdef TIXML_USE_STL
1271     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1272     #endif
1273 
1274 private:
1275     bool cdata;         // true if this should be input and output as a CDATA style text element
1276 };
1277 
1278 
1279 /** In correct XML the declaration is the first entry in the file.
1280     @verbatim
1281         <?xml version="1.0" standalone="yes"?>
1282     @endverbatim
1283 
1284     TinyXml will happily read or write files without a declaration,
1285     however. There are 3 possible attributes to the declaration:
1286     version, encoding, and standalone.
1287 
1288     Note: In this version of the code, the attributes are
1289     handled as special cases, not generic attributes, simply
1290     because there can only be at most 3 and they are always the same.
1291 */
1292 class TiXmlDeclaration : public TiXmlNode
1293 {
1294 public:
1295     /// Construct an empty declaration.
1296     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
1297 
1298 #ifdef TIXML_USE_STL
1299     /// Constructor.
1300     TiXmlDeclaration(   const std::string& _version,
1301                         const std::string& _encoding,
1302                         const std::string& _standalone );
1303 #endif
1304 
1305     /// Construct.
1306     TiXmlDeclaration(   const char* _version,
1307                         const char* _encoding,
1308                         const char* _standalone );
1309 
1310     TiXmlDeclaration( const TiXmlDeclaration& copy );
1311     TiXmlDeclaration& operator=( const TiXmlDeclaration& copy );
1312 
1313     virtual ~TiXmlDeclaration() {}
1314 
1315     /// Version. Will return an empty string if none was found.
1316     const char *Version() const         { return version.c_str (); }
1317     /// Encoding. Will return an empty string if none was found.
1318     const char *Encoding() const        { return encoding.c_str (); }
1319     /// Is this a standalone document?
1320     const char *Standalone() const      { return standalone.c_str (); }
1321 
1322     /// Creates a copy of this Declaration and returns it.
1323     virtual TiXmlNode* Clone() const;
1324     // Print this declaration to a FILE stream.
1325     virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
1326     virtual void Print( FILE* cfile, int depth ) const {
1327         Print( cfile, depth, 0 );
1328     }
1329 
1330     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1331 
1332     virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1333     virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1334 
1335     /** Walk the XML tree visiting this node and all of its children. 
1336     */
1337     virtual bool Accept( TiXmlVisitor* visitor ) const;
1338 
1339 protected:
1340     void CopyTo( TiXmlDeclaration* target ) const;
1341     // used to be public
1342     #ifdef TIXML_USE_STL
1343     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1344     #endif
1345 
1346 private:
1347 
1348     TIXML_STRING version;
1349     TIXML_STRING encoding;
1350     TIXML_STRING standalone;
1351 };
1352 
1353 
1354 /** Any tag that tinyXml doesn't recognize is saved as an
1355     unknown. It is a tag of text, but should not be modified.
1356     It will be written back to the XML, unchanged, when the file
1357     is saved.
1358 
1359     DTD tags get thrown into TiXmlUnknowns.
1360 */
1361 class TiXmlUnknown : public TiXmlNode
1362 {
1363 public:
1364     TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )    {}
1365     virtual ~TiXmlUnknown() {}
1366 
1367     TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )      { copy.CopyTo( this ); }
1368     TiXmlUnknown& operator=( const TiXmlUnknown& copy )                                     { copy.CopyTo( this ); return *this; }
1369 
1370     /// Creates a copy of this Unknown and returns it.
1371     virtual TiXmlNode* Clone() const;
1372     // Print this Unknown to a FILE stream.
1373     virtual void Print( FILE* cfile, int depth ) const;
1374 
1375     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1376 
1377     virtual const TiXmlUnknown*     ToUnknown()     const   { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1378     virtual TiXmlUnknown*           ToUnknown()             { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1379 
1380     /** Walk the XML tree visiting this node and all of its children. 
1381     */
1382     virtual bool Accept( TiXmlVisitor* content ) const;
1383 
1384 protected:
1385     void CopyTo( TiXmlUnknown* target ) const;
1386 
1387     #ifdef TIXML_USE_STL
1388     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1389     #endif
1390 
1391 private:
1392 
1393 };
1394 
1395 
1396 /** Always the top level node. A document binds together all the
1397     XML pieces. It can be saved, loaded, and printed to the screen.
1398     The 'value' of a document node is the xml file name.
1399 */
1400 class TiXmlDocument : public TiXmlNode
1401 {
1402 public:
1403     /// Create an empty document, that has no name.
1404     TiXmlDocument();
1405     /// Create a document with a name. The name of the document is also the filename of the xml.
1406     TiXmlDocument( const char * documentName );
1407 
1408     #ifdef TIXML_USE_STL
1409     /// Constructor.
1410     TiXmlDocument( const std::string& documentName );
1411     #endif
1412 
1413     TiXmlDocument( const TiXmlDocument& copy );
1414     TiXmlDocument& operator=( const TiXmlDocument& copy );
1415 
1416     virtual ~TiXmlDocument() {}
1417 
1418     /** Load a file using the current document value.
1419         Returns true if successful. Will delete any existing
1420         document data before loading.
1421     */
1422     bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1423     /// Save a file using the current document value. Returns true if successful.
1424     bool SaveFile() const;
1425     /// Load a file using the given filename. Returns true if successful.
1426     bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1427     /// Save a file using the given filename. Returns true if successful.
1428     bool SaveFile( const char * filename ) const;
1429     /** Load a file using the given FILE*. Returns true if successful. Note that this method
1430         doesn't stream - the entire object pointed at by the FILE*
1431         will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
1432         file location. Streaming may be added in the future.
1433     */
1434     bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1435     /// Save a file using the given FILE*. Returns true if successful.
1436     bool SaveFile( FILE* ) const;
1437 
1438     #ifdef TIXML_USE_STL
1439     bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )           ///< STL std::string version.
1440     {
1441         return LoadFile( filename.c_str(), encoding );
1442     }
1443     bool SaveFile( const std::string& filename ) const      ///< STL std::string version.
1444     {
1445         return SaveFile( filename.c_str() );
1446     }
1447     #endif
1448 
1449     /** Parse the given null terminated block of xml data. Passing in an encoding to this
1450         method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
1451         to use that encoding, regardless of what TinyXml might otherwise try to detect.
1452     */
1453     virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1454 
1455     /** Get the root element -- the only top level element -- of the document.
1456         In well formed XML, there should only be one. TinyXml is tolerant of
1457         multiple elements at the document level.
1458     */
1459     const TiXmlElement* RootElement() const     { return FirstChildElement(); }
1460     TiXmlElement* RootElement()                 { return FirstChildElement(); }
1461 
1462     /** If an error occurs, Error will be set to true. Also,
1463         - The ErrorId() will contain the integer identifier of the error (not generally useful)
1464         - The ErrorDesc() method will return the name of the error. (very useful)
1465         - The ErrorRow() and ErrorCol() will return the location of the error (if known)
1466     */  
1467     bool Error() const                      { return error; }
1468 
1469     /// Contains a textual (english) description of the error if one occurs.
1470     const char * ErrorDesc() const  { return errorDesc.c_str (); }
1471 
1472     /** Generally, you probably want the error string ( ErrorDesc() ). But if you
1473         prefer the ErrorId, this function will fetch it.
1474     */
1475     int ErrorId()   const               { return errorId; }
1476 
1477     /** Returns the location (if known) of the error. The first column is column 1, 
1478         and the first row is row 1. A value of 0 means the row and column wasn't applicable
1479         (memory errors, for example, have no row/column) or the parser lost the error. (An
1480         error in the error reporting, in that case.)
1481 
1482         @sa SetTabSize, Row, Column
1483     */
1484     int ErrorRow() const    { return errorLocation.row+1; }
1485     int ErrorCol() const    { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
1486 
1487     /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
1488         to report the correct values for row and column. It does not change the output
1489         or input in any way.
1490         
1491         By calling this method, with a tab size
1492         greater than 0, the row and column of each node and attribute is stored
1493         when the file is loaded. Very useful for tracking the DOM back in to
1494         the source file.
1495 
1496         The tab size is required for calculating the location of nodes. If not
1497         set, the default of 4 is used. The tabsize is set per document. Setting
1498         the tabsize to 0 disables row/column tracking.
1499 
1500         Note that row and column tracking is not supported when using operator>>.
1501 
1502         The tab size needs to be enabled before the parse or load. Correct usage:
1503         @verbatim
1504         TiXmlDocument doc;
1505         doc.SetTabSize( 8 );
1506         doc.Load( "myfile.xml" );
1507         @endverbatim
1508 
1509         @sa Row, Column
1510     */
1511     void SetTabSize( int _tabsize )     { tabsize = _tabsize; }
1512 
1513     int TabSize() const { return tabsize; }
1514 
1515     /** If you have handled the error, it can be reset with this call. The error
1516         state is automatically cleared if you Parse a new XML block.
1517     */
1518     void ClearError()                       {   error = false; 
1519                                                 errorId = 0; 
1520                                                 errorDesc = ""; 
1521                                                 errorLocation.row = errorLocation.col = 0; 
1522                                                 //errorLocation.last = 0; 
1523                                             }
1524 
1525     /** Write the document to standard out using formatted printing ("pretty print"). */
1526     void Print() const                      { Print( stdout, 0 ); }
1527 
1528     /* Write the document to a string using formatted printing ("pretty print"). This
1529         will allocate a character array (new char[]) and return it as a pointer. The
1530         calling code pust call delete[] on the return char* to avoid a memory leak.
1531     */
1532     //char* PrintToMemory() const; 
1533 
1534     /// Print this Document to a FILE stream.
1535     virtual void Print( FILE* cfile, int depth = 0 ) const;
1536     // [internal use]
1537     void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1538 
1539     virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1540     virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1541 
1542     /** Walk the XML tree visiting this node and all of its children. 
1543     */
1544     virtual bool Accept( TiXmlVisitor* content ) const;
1545 
1546 protected :
1547     // [internal use]
1548     virtual TiXmlNode* Clone() const;
1549     #ifdef TIXML_USE_STL
1550     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1551     #endif
1552 
1553 private:
1554     void CopyTo( TiXmlDocument* target ) const;
1555 
1556     bool error;
1557     int  errorId;
1558     TIXML_STRING errorDesc;
1559     int tabsize;
1560     TiXmlCursor errorLocation;
1561     bool useMicrosoftBOM;       // the UTF-8 BOM were found when read. Note this, and try to write.
1562 };
1563 
1564 
1565 /**
1566     A TiXmlHandle is a class that wraps a node pointer with null checks; this is
1567     an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
1568     DOM structure. It is a separate utility class.
1569 
1570     Take an example:
1571     @verbatim
1572     <Document>
1573         <Element attributeA = "valueA">
1574             <Child attributeB = "value1" />
1575             <Child attributeB = "value2" />
1576         </Element>
1577     <Document>
1578     @endverbatim
1579 
1580     Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
1581     easy to write a *lot* of code that looks like:
1582 
1583     @verbatim
1584     TiXmlElement* root = document.FirstChildElement( "Document" );
1585     if ( root )
1586     {
1587         TiXmlElement* element = root->FirstChildElement( "Element" );
1588         if ( element )
1589         {
1590             TiXmlElement* child = element->FirstChildElement( "Child" );
1591             if ( child )
1592             {
1593                 TiXmlElement* child2 = child->NextSiblingElement( "Child" );
1594                 if ( child2 )
1595                 {
1596                     // Finally do something useful.
1597     @endverbatim
1598 
1599     And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
1600     of such code. A TiXmlHandle checks for null pointers so it is perfectly safe 
1601     and correct to use:
1602 
1603     @verbatim
1604     TiXmlHandle docHandle( &document );
1605     TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
1606     if ( child2 )
1607     {
1608         // do something useful
1609     @endverbatim
1610 
1611     Which is MUCH more concise and useful.
1612 
1613     It is also safe to copy handles - internally they are nothing more than node pointers.
1614     @verbatim
1615     TiXmlHandle handleCopy = handle;
1616     @endverbatim
1617 
1618     What they should not be used for is iteration:
1619 
1620     @verbatim
1621     int i=0; 
1622     while ( true )
1623     {
1624         TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
1625         if ( !child )
1626             break;
1627         // do something
1628         ++i;
1629     }
1630     @endverbatim
1631 
1632     It seems reasonable, but it is in fact two embedded while loops. The Child method is 
1633     a linear walk to find the element, so this code would iterate much more than it needs 
1634     to. Instead, prefer:
1635 
1636     @verbatim
1637     TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
1638 
1639     for( child; child; child=child->NextSiblingElement() )
1640     {
1641         // do something
1642     }
1643     @endverbatim
1644 */
1645 class TiXmlHandle
1646 {
1647 public:
1648     /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
1649     TiXmlHandle( TiXmlNode* _node )                 { this->node = _node; }
1650     /// Copy constructor
1651     TiXmlHandle( const TiXmlHandle& ref )           { this->node = ref.node; }
1652     TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; }
1653 
1654     /// Return a handle to the first child node.
1655     TiXmlHandle FirstChild() const;
1656     /// Return a handle to the first child node with the given name.
1657     TiXmlHandle FirstChild( const char * value ) const;
1658     /// Return a handle to the first child element.
1659     TiXmlHandle FirstChildElement() const;
1660     /// Return a handle to the first child element with the given name.
1661     TiXmlHandle FirstChildElement( const char * value ) const;
1662 
1663     /** Return a handle to the "index" child with the given name. 
1664         The first child is 0, the second 1, etc.
1665     */
1666     TiXmlHandle Child( const char* value, int index ) const;
1667     /** Return a handle to the "index" child. 
1668         The first child is 0, the second 1, etc.
1669     */
1670     TiXmlHandle Child( int index ) const;
1671     /** Return a handle to the "index" child element with the given name. 
1672         The first child element is 0, the second 1, etc. Note that only TiXmlElements
1673         are indexed: other types are not counted.
1674     */
1675     TiXmlHandle ChildElement( const char* value, int index ) const;
1676     /** Return a handle to the "index" child element. 
1677         The first child element is 0, the second 1, etc. Note that only TiXmlElements
1678         are indexed: other types are not counted.
1679     */
1680     TiXmlHandle ChildElement( int index ) const;
1681 
1682     #ifdef TIXML_USE_STL
1683     TiXmlHandle FirstChild( const std::string& _value ) const               { return FirstChild( _value.c_str() ); }
1684     TiXmlHandle FirstChildElement( const std::string& _value ) const        { return FirstChildElement( _value.c_str() ); }
1685 
1686     TiXmlHandle Child( const std::string& _value, int index ) const         { return Child( _value.c_str(), index ); }
1687     TiXmlHandle ChildElement( const std::string& _value, int index ) const  { return ChildElement( _value.c_str(), index ); }
1688     #endif
1689 
1690     /** Return the handle as a TiXmlNode. This may return null.
1691     */
1692     TiXmlNode* ToNode() const           { return node; } 
1693     /** Return the handle as a TiXmlElement. This may return null.
1694     */
1695     TiXmlElement* ToElement() const     { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
1696     /** Return the handle as a TiXmlText. This may return null.
1697     */
1698     TiXmlText* ToText() const           { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
1699     /** Return the handle as a TiXmlUnknown. This may return null.
1700     */
1701     TiXmlUnknown* ToUnknown() const     { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
1702 
1703     /** @deprecated use ToNode. 
1704         Return the handle as a TiXmlNode. This may return null.
1705     */
1706     TiXmlNode* Node() const         { return ToNode(); } 
1707     /** @deprecated use ToElement. 
1708         Return the handle as a TiXmlElement. This may return null.
1709     */
1710     TiXmlElement* Element() const   { return ToElement(); }
1711     /** @deprecated use ToText()
1712         Return the handle as a TiXmlText. This may return null.
1713     */
1714     TiXmlText* Text() const         { return ToText(); }
1715     /** @deprecated use ToUnknown()
1716         Return the handle as a TiXmlUnknown. This may return null.
1717     */
1718     TiXmlUnknown* Unknown() const   { return ToUnknown(); }
1719 
1720 private:
1721     TiXmlNode* node;
1722 };
1723 
1724 
1725 /** Print to memory functionality. The TiXmlPrinter is useful when you need to:
1726 
1727     -# Print to memory (especially in non-STL mode)
1728     -# Control formatting (line endings, etc.)
1729 
1730     When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
1731     Before calling Accept() you can call methods to control the printing
1732     of the XML document. After TiXmlNode::Accept() is called, the printed document can
1733     be accessed via the CStr(), Str(), and Size() methods.
1734 
1735     TiXmlPrinter uses the Visitor API.
1736     @verbatim
1737     TiXmlPrinter printer;
1738     printer.SetIndent( "\t" );
1739 
1740     doc.Accept( &printer );
1741     fprintf( stdout, "%s", printer.CStr() );
1742     @endverbatim
1743 */
1744 class TiXmlPrinter : public TiXmlVisitor
1745 {
1746 public:
1747     TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
1748                      buffer(), indent( "    " ), lineBreak( "\n" ) {}
1749 
1750     virtual bool VisitEnter( const TiXmlDocument& doc );
1751     virtual bool VisitExit( const TiXmlDocument& doc );
1752 
1753     virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
1754     virtual bool VisitExit( const TiXmlElement& element );
1755 
1756     virtual bool Visit( const TiXmlDeclaration& declaration );
1757     virtual bool Visit( const TiXmlText& text );
1758     virtual bool Visit( const TiXmlComment& comment );
1759     virtual bool Visit( const TiXmlUnknown& unknown );
1760 
1761     /** Set the indent characters for printing. By default 4 spaces
1762         but tab (\t) is also useful, or null/empty string for no indentation.
1763     */
1764     void SetIndent( const char* _indent )           { indent = _indent ? _indent : "" ; }
1765     /// Query the indention string.
1766     const char* Indent()                            { return indent.c_str(); }
1767     /** Set the line breaking string. By default set to newline (\n). 
1768         Some operating systems prefer other characters, or can be
1769         set to the null/empty string for no indenation.
1770     */
1771     void SetLineBreak( const char* _lineBreak )     { lineBreak = _lineBreak ? _lineBreak : ""; }
1772     /// Query the current line breaking string.
1773     const char* LineBreak()                         { return lineBreak.c_str(); }
1774 
1775     /** Switch over to "stream printing" which is the most dense formatting without 
1776         linebreaks. Common when the XML is needed for network transmission.
1777     */
1778     void SetStreamPrinting()                        { indent = "";
1779                                                       lineBreak = "";
1780                                                     }   
1781     /// Return the result.
1782     const char* CStr()                              { return buffer.c_str(); }
1783     /// Return the length of the result string.
1784     size_t Size()                                   { return buffer.size(); }
1785 
1786     #ifdef TIXML_USE_STL
1787     /// Return the result.
1788     const std::string& Str()                        { return buffer; }
1789     #endif
1790 
1791 private:
1792     void DoIndent() {
1793         for( int i=0; i<depth; ++i )
1794             buffer += indent;
1795     }
1796     void DoLineBreak() {
1797         buffer += lineBreak;
1798     }
1799 
1800     int depth;
1801     bool simpleTextPrint;
1802     TIXML_STRING buffer;
1803     TIXML_STRING indent;
1804     TIXML_STRING lineBreak;
1805 };
1806 
1807 
1808 #ifdef _MSC_VER
1809 #pragma warning( pop )
1810 #endif
1811 
1812 } // Added namespace pandora
1813 
1814 #endif // PANDORA_TINYXML_INCLUDED