Wim van der Vegt / TINYXML

Dependents:   tinyxml_test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tinyxml.h Source File

tinyxml.h

00001 /*
00002 www.sourceforge.net/projects/tinyxml
00003 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
00004 
00005 This software is provided 'as-is', without any express or implied
00006 warranty. In no event will the authors be held liable for any
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any
00010 purpose, including commercial applications, and to alter it and
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must
00014 not claim that you wrote the original software. If you use this
00015 software in a product, an acknowledgment in the product documentation
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source
00022 distribution.
00023 */
00024 
00025 //veg: added
00026 //#define TIXML_USE_STL
00027 
00028 #ifndef TINYXML_INCLUDED
00029 #define TINYXML_INCLUDED
00030 
00031 #ifdef _MSC_VER
00032 #pragma warning( push )
00033 #pragma warning( disable : 4530 )
00034 #pragma warning( disable : 4786 )
00035 #endif
00036 
00037 #include <ctype.h>
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <assert.h>
00042 
00043 // Help out windows:
00044 #if defined( _DEBUG ) && !defined( DEBUG )
00045 #define DEBUG
00046 #endif
00047 
00048 #ifdef TIXML_USE_STL
00049     #include <string>
00050      #include <iostream>
00051     #include <sstream>
00052     #define TIXML_STRING        std::string
00053 #else
00054     #include "tinystr.h"
00055     #define TIXML_STRING        TiXmlString
00056 #endif
00057 
00058 // Deprecated library function hell. Compilers want to use the
00059 // new safe versions. This probably doesn't fully address the problem,
00060 // but it gets closer. There are too many compilers for me to fully
00061 // test. If you get compilation troubles, undefine TIXML_SAFE
00062 #define TIXML_SAFE
00063 
00064 #ifdef TIXML_SAFE
00065     #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
00066         // Microsoft visual studio, version 2005 and higher.
00067         #define TIXML_SNPRINTF _snprintf_s
00068         #define TIXML_SSCANF   sscanf_s
00069     #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
00070         // Microsoft visual studio, version 6 and higher.
00071         //#pragma message( "Using _sn* functions." )
00072         #define TIXML_SNPRINTF _snprintf
00073         #define TIXML_SSCANF   sscanf
00074     #elif defined(__GNUC__) && (__GNUC__ >= 3 )
00075         // GCC version 3 and higher.s
00076         //#warning( "Using sn* functions." )
00077         #define TIXML_SNPRINTF snprintf
00078         #define TIXML_SSCANF   sscanf
00079     #else
00080         #define TIXML_SNPRINTF snprintf
00081         #define TIXML_SSCANF   sscanf
00082     #endif
00083 #endif    
00084 
00085 class TiXmlDocument;
00086 class TiXmlElement;
00087 class TiXmlComment;
00088 class TiXmlUnknown;
00089 class TiXmlAttribute;
00090 class TiXmlText;
00091 class TiXmlDeclaration;
00092 class TiXmlParsingData;
00093 
00094 const int TIXML_MAJOR_VERSION = 2;
00095 const int TIXML_MINOR_VERSION = 6;
00096 const int TIXML_PATCH_VERSION = 1;
00097 
00098 /*    Internal structure for tracking location of items 
00099     in the XML file.
00100 */
00101 struct TiXmlCursor
00102 {
00103     TiXmlCursor()        { Clear(); }
00104     void Clear()        { row = col = -1; }
00105 
00106     int row;    // 0 based.
00107     int col;    // 0 based.
00108 };
00109 
00110 
00111 /**
00112     Implements the interface to the "Visitor pattern" (see the Accept() method.)
00113     If you call the Accept() method, it requires being passed a TiXmlVisitor
00114     class to handle callbacks. For nodes that contain other nodes (Document, Element)
00115     you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
00116     are simply called with Visit().
00117 
00118     If you return 'true' from a Visit method, recursive parsing will continue. If you return
00119     false, <b>no children of this node or its sibilings</b> will be Visited.
00120 
00121     All flavors of Visit methods have a default implementation that returns 'true' (continue 
00122     visiting). You need to only override methods that are interesting to you.
00123 
00124     Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
00125 
00126     You should never change the document from a callback.
00127 
00128     @sa TiXmlNode::Accept()
00129 */
00130 class TiXmlVisitor
00131 {
00132 public:
00133     virtual ~TiXmlVisitor() {}
00134 
00135     /// Visit a document.
00136     virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )            { return true; }
00137     /// Visit a document.
00138     virtual bool VisitExit( const TiXmlDocument& /*doc*/ )            { return true; }
00139 
00140     /// Visit an element.
00141     virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )    { return true; }
00142     /// Visit an element.
00143     virtual bool VisitExit( const TiXmlElement& /*element*/ )        { return true; }
00144 
00145     /// Visit a declaration
00146     virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )    { return true; }
00147     /// Visit a text node
00148     virtual bool Visit( const TiXmlText& /*text*/ )                    { return true; }
00149     /// Visit a comment node
00150     virtual bool Visit( const TiXmlComment& /*comment*/ )            { return true; }
00151     /// Visit an unknow node
00152     virtual bool Visit( const TiXmlUnknown& /*unknown*/ )            { return true; }
00153 };
00154 
00155 // Only used by Attribute::Query functions
00156 enum 
00157 { 
00158     TIXML_SUCCESS,
00159     TIXML_NO_ATTRIBUTE,
00160     TIXML_WRONG_TYPE
00161 };
00162 
00163 
00164 // Used by the parsing routines.
00165 enum TiXmlEncoding
00166 {
00167     TIXML_ENCODING_UNKNOWN,
00168     TIXML_ENCODING_UTF8,
00169     TIXML_ENCODING_LEGACY
00170 };
00171 
00172 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
00173 
00174 /** TiXmlBase is a base class for every class in TinyXml.
00175     It does little except to establish that TinyXml classes
00176     can be printed and provide some utility functions.
00177 
00178     In XML, the document and elements can contain
00179     other elements and other types of nodes.
00180 
00181     @verbatim
00182     A Document can contain:    Element    (container or leaf)
00183                             Comment (leaf)
00184                             Unknown (leaf)
00185                             Declaration( leaf )
00186 
00187     An Element can contain:    Element (container or leaf)
00188                             Text    (leaf)
00189                             Attributes (not on tree)
00190                             Comment (leaf)
00191                             Unknown (leaf)
00192 
00193     A Decleration contains: Attributes (not on tree)
00194     @endverbatim
00195 */
00196 class TiXmlBase
00197 {
00198     friend class TiXmlNode;
00199     friend class TiXmlElement;
00200     friend class TiXmlDocument;
00201 
00202 public:
00203     TiXmlBase()    :    userData(0)        {}
00204     virtual ~TiXmlBase()            {}
00205 
00206     /**    All TinyXml classes can print themselves to a filestream
00207         or the string class (TiXmlString in non-STL mode, std::string
00208         in STL mode.) Either or both cfile and str can be null.
00209         
00210         This is a formatted print, and will insert 
00211         tabs and newlines.
00212         
00213         (For an unformatted stream, use the << operator.)
00214     */
00215     virtual void Print( FILE* cfile, int depth ) const = 0;
00216 
00217     /**    The world does not agree on whether white space should be kept or
00218         not. In order to make everyone happy, these global, static functions
00219         are provided to set whether or not TinyXml will condense all white space
00220         into a single space or not. The default is to condense. Note changing this
00221         value is not thread safe.
00222     */
00223     static void SetCondenseWhiteSpace( bool condense )        { condenseWhiteSpace = condense; }
00224 
00225     /// Return the current white space setting.
00226     static bool IsWhiteSpaceCondensed()                        { return condenseWhiteSpace; }
00227 
00228     /** Return the position, in the original source file, of this node or attribute.
00229         The row and column are 1-based. (That is the first row and first column is
00230         1,1). If the returns values are 0 or less, then the parser does not have
00231         a row and column value.
00232 
00233         Generally, the row and column value will be set when the TiXmlDocument::Load(),
00234         TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
00235         when the DOM was created from operator>>.
00236 
00237         The values reflect the initial load. Once the DOM is modified programmatically
00238         (by adding or changing nodes and attributes) the new values will NOT update to
00239         reflect changes in the document.
00240 
00241         There is a minor performance cost to computing the row and column. Computation
00242         can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
00243 
00244         @sa TiXmlDocument::SetTabSize()
00245     */
00246     int Row() const            { return location.row + 1; }
00247     int Column() const        { return location.col + 1; }    ///< See Row()
00248 
00249     void  SetUserData( void* user )            { userData = user; }    ///< Set a pointer to arbitrary user data.
00250     void* GetUserData()                        { return userData; }    ///< Get a pointer to arbitrary user data.
00251     const void* GetUserData() const         { return userData; }    ///< Get a pointer to arbitrary user data.
00252 
00253     // Table that returs, for a given lead byte, the total number of bytes
00254     // in the UTF-8 sequence.
00255     static const int utf8ByteTable[256];
00256 
00257     virtual const char* Parse(    const char* p, 
00258                                 TiXmlParsingData* data, 
00259                                 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
00260 
00261     /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, 
00262         or they will be transformed into entities!
00263     */
00264     static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
00265 
00266     enum
00267     {
00268         TIXML_NO_ERROR = 0,
00269         TIXML_ERROR,
00270         TIXML_ERROR_OPENING_FILE,
00271         TIXML_ERROR_PARSING_ELEMENT,
00272         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00273         TIXML_ERROR_READING_ELEMENT_VALUE,
00274         TIXML_ERROR_READING_ATTRIBUTES,
00275         TIXML_ERROR_PARSING_EMPTY,
00276         TIXML_ERROR_READING_END_TAG,
00277         TIXML_ERROR_PARSING_UNKNOWN,
00278         TIXML_ERROR_PARSING_COMMENT,
00279         TIXML_ERROR_PARSING_DECLARATION,
00280         TIXML_ERROR_DOCUMENT_EMPTY,
00281         TIXML_ERROR_EMBEDDED_NULL,
00282         TIXML_ERROR_PARSING_CDATA,
00283         TIXML_ERROR_DOCUMENT_TOP_ONLY,
00284 
00285         TIXML_ERROR_STRING_COUNT
00286     };
00287 
00288 protected:
00289 
00290     static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
00291 
00292     inline static bool IsWhiteSpace( char c )        
00293     { 
00294         return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
00295     }
00296     inline static bool IsWhiteSpace( int c )
00297     {
00298         if ( c < 256 )
00299             return IsWhiteSpace( (char) c );
00300         return false;    // Again, only truly correct for English/Latin...but usually works.
00301     }
00302 
00303     #ifdef TIXML_USE_STL
00304     static bool    StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
00305     static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
00306     #endif
00307 
00308     /*    Reads an XML name into the string provided. Returns
00309         a pointer just past the last character of the name,
00310         or 0 if the function has an error.
00311     */
00312     static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
00313 
00314     /*    Reads text. Returns a pointer past the given end tag.
00315         Wickedly complex options, but it keeps the (sensitive) code in one place.
00316     */
00317     static const char* ReadText(    const char* in,                // where to start
00318                                     TIXML_STRING* text,            // the string read
00319                                     bool ignoreWhiteSpace,        // whether to keep the white space
00320                                     const char* endTag,            // what ends this text
00321                                     bool ignoreCase,            // whether to ignore case in the end tag
00322                                     TiXmlEncoding encoding );    // the current encoding
00323 
00324     // If an entity has been found, transform it into a character.
00325     static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
00326 
00327     // Get a character, while interpreting entities.
00328     // The length can be from 0 to 4 bytes.
00329     inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
00330     {
00331         assert( p );
00332         if ( encoding == TIXML_ENCODING_UTF8 )
00333         {
00334             *length = utf8ByteTable[ *((const unsigned char*)p) ];
00335             assert( *length >= 0 && *length < 5 );
00336         }
00337         else
00338         {
00339             *length = 1;
00340         }
00341 
00342         if ( *length == 1 )
00343         {
00344             if ( *p == '&' )
00345                 return GetEntity( p, _value, length, encoding );
00346             *_value = *p;
00347             return p+1;
00348         }
00349         else if ( *length )
00350         {
00351             //strncpy( _value, p, *length );    // lots of compilers don't like this function (unsafe),
00352                                                 // and the null terminator isn't needed
00353             for( int i=0; p[i] && i<*length; ++i ) {
00354                 _value[i] = p[i];
00355             }
00356             return p + (*length);
00357         }
00358         else
00359         {
00360             // Not valid text.
00361             return 0;
00362         }
00363     }
00364 
00365     // Return true if the next characters in the stream are any of the endTag sequences.
00366     // Ignore case only works for english, and should only be relied on when comparing
00367     // to English words: StringEqual( p, "version", true ) is fine.
00368     static bool StringEqual(    const char* p,
00369                                 const char* endTag,
00370                                 bool ignoreCase,
00371                                 TiXmlEncoding encoding );
00372 
00373     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00374 
00375     TiXmlCursor location;
00376 
00377     /// Field containing a generic user pointer
00378     void*            userData;
00379     
00380     // None of these methods are reliable for any language except English.
00381     // Good for approximation, not great for accuracy.
00382     static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
00383     static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
00384     inline static int ToLower( int v, TiXmlEncoding encoding )
00385     {
00386         if ( encoding == TIXML_ENCODING_UTF8 )
00387         {
00388             if ( v < 128 ) return tolower( v );
00389             return v;
00390         }
00391         else
00392         {
00393             return tolower( v );
00394         }
00395     }
00396     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00397 
00398 private:
00399     TiXmlBase( const TiXmlBase& );                // not implemented.
00400     void operator=( const TiXmlBase& base );    // not allowed.
00401 
00402     struct Entity
00403     {
00404         const char*     str;
00405         unsigned int    strLength;
00406         char            chr;
00407     };
00408     enum
00409     {
00410         NUM_ENTITY = 5,
00411         MAX_ENTITY_LENGTH = 6
00412 
00413     };
00414     static Entity entity[ NUM_ENTITY ];
00415     static bool condenseWhiteSpace;
00416 };
00417 
00418 
00419 /** The parent class for everything in the Document Object Model.
00420     (Except for attributes).
00421     Nodes have siblings, a parent, and children. A node can be
00422     in a document, or stand on its own. The type of a TiXmlNode
00423     can be queried, and it can be cast to its more defined type.
00424 */
00425 class TiXmlNode : public TiXmlBase
00426 {
00427     friend class TiXmlDocument;
00428     friend class TiXmlElement;
00429 
00430 public:
00431     #ifdef TIXML_USE_STL    
00432 
00433         /** An input stream operator, for every class. Tolerant of newlines and
00434             formatting, but doesn't expect them.
00435         */
00436         friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00437 
00438         /** An output stream operator, for every class. Note that this outputs
00439             without any newlines or formatting, as opposed to Print(), which
00440             includes tabs and new lines.
00441 
00442             The operator<< and operator>> are not completely symmetric. Writing
00443             a node to a stream is very well defined. You'll get a nice stream
00444             of output, without any extra whitespace or newlines.
00445             
00446             But reading is not as well defined. (As it always is.) If you create
00447             a TiXmlElement (for example) and read that from an input stream,
00448             the text needs to define an element or junk will result. This is
00449             true of all input streams, but it's worth keeping in mind.
00450 
00451             A TiXmlDocument will read nodes until it reads a root element, and
00452             all the children of that root element.
00453         */    
00454         friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
00455 
00456         /// Appends the XML node or attribute to a std::string.
00457         friend std::string& operator<< (std::string& out, const TiXmlNode& base );
00458 
00459     #endif
00460 
00461     /** The types of XML nodes supported by TinyXml. (All the
00462             unsupported types are picked up by UNKNOWN.)
00463     */
00464     enum NodeType
00465     {
00466         TINYXML_DOCUMENT,
00467         TINYXML_ELEMENT,
00468         TINYXML_COMMENT,
00469         TINYXML_UNKNOWN,
00470         TINYXML_TEXT,
00471         TINYXML_DECLARATION,
00472         TINYXML_TYPECOUNT
00473     };
00474 
00475     virtual ~TiXmlNode();
00476 
00477     /** The meaning of 'value' changes for the specific type of
00478         TiXmlNode.
00479         @verbatim
00480         Document:    filename of the xml file
00481         Element:    name of the element
00482         Comment:    the comment text
00483         Unknown:    the tag contents
00484         Text:        the text string
00485         @endverbatim
00486 
00487         The subclasses will wrap this function.
00488     */
00489     const char *Value() const { return value.c_str (); }
00490 
00491     #ifdef TIXML_USE_STL
00492     /** Return Value() as a std::string. If you only use STL,
00493         this is more efficient than calling Value().
00494         Only available in STL mode.
00495     */
00496     const std::string& ValueStr() const { return value; }
00497     #endif
00498 
00499     const TIXML_STRING& ValueTStr() const { return value; }
00500 
00501     /** Changes the value of the node. Defined as:
00502         @verbatim
00503         Document:    filename of the xml file
00504         Element:    name of the element
00505         Comment:    the comment text
00506         Unknown:    the tag contents
00507         Text:        the text string
00508         @endverbatim
00509     */
00510     void SetValue(const char * _value) { value = _value;}
00511 
00512     #ifdef TIXML_USE_STL
00513     /// STL std::string form.
00514     void SetValue( const std::string& _value )    { value = _value; }
00515     #endif
00516 
00517     /// Delete all the children of this node. Does not affect 'this'.
00518     void Clear();
00519 
00520     /// One step up the DOM.
00521     TiXmlNode* Parent()                            { return parent; }
00522     const TiXmlNode* Parent() const                { return parent; }
00523 
00524     const TiXmlNode* FirstChild()    const        { return firstChild; }    ///< The first child of this node. Will be null if there are no children.
00525     TiXmlNode* FirstChild()                        { return firstChild; }
00526     const TiXmlNode* FirstChild( const char * value ) const;            ///< The first child of this node with the matching 'value'. Will be null if none found.
00527     /// The first child of this node with the matching 'value'. Will be null if none found.
00528     TiXmlNode* FirstChild( const char * _value ) {
00529         // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
00530         // call the method, cast the return back to non-const.
00531         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
00532     }
00533     const TiXmlNode* LastChild() const    { return lastChild; }        /// The last child of this node. Will be null if there are no children.
00534     TiXmlNode* LastChild()    { return lastChild; }
00535     
00536     const TiXmlNode* LastChild( const char * value ) const;            /// The last child of this node matching 'value'. Will be null if there are no children.
00537     TiXmlNode* LastChild( const char * _value ) {
00538         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
00539     }
00540 
00541     #ifdef TIXML_USE_STL
00542     const TiXmlNode* FirstChild( const std::string& _value ) const    {    return FirstChild (_value.c_str ());    }    ///< STL std::string form.
00543     TiXmlNode* FirstChild( const std::string& _value )                {    return FirstChild (_value.c_str ());    }    ///< STL std::string form.
00544     const TiXmlNode* LastChild( const std::string& _value ) const    {    return LastChild (_value.c_str ());    }    ///< STL std::string form.
00545     TiXmlNode* LastChild( const std::string& _value )                {    return LastChild (_value.c_str ());    }    ///< STL std::string form.
00546     #endif
00547 
00548     /** An alternate way to walk the children of a node.
00549         One way to iterate over nodes is:
00550         @verbatim
00551             for( child = parent->FirstChild(); child; child = child->NextSibling() )
00552         @endverbatim
00553 
00554         IterateChildren does the same thing with the syntax:
00555         @verbatim
00556             child = 0;
00557             while( child = parent->IterateChildren( child ) )
00558         @endverbatim
00559 
00560         IterateChildren takes the previous child as input and finds
00561         the next one. If the previous child is null, it returns the
00562         first. IterateChildren will return null when done.
00563     */
00564     const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
00565     TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
00566         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
00567     }
00568 
00569     /// This flavor of IterateChildren searches for children with a particular 'value'
00570     const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
00571     TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
00572         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
00573     }
00574 
00575     #ifdef TIXML_USE_STL
00576     const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const    {    return IterateChildren (_value.c_str (), previous);    }    ///< STL std::string form.
00577     TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {    return IterateChildren (_value.c_str (), previous);    }    ///< STL std::string form.
00578     #endif
00579 
00580     /** Add a new node related to this. Adds a child past the LastChild.
00581         Returns a pointer to the new object or NULL if an error occured.
00582     */
00583     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00584 
00585 
00586     /** Add a new node related to this. Adds a child past the LastChild.
00587 
00588         NOTE: the node to be added is passed by pointer, and will be
00589         henceforth owned (and deleted) by tinyXml. This method is efficient
00590         and avoids an extra copy, but should be used with care as it
00591         uses a different memory model than the other insert functions.
00592 
00593         @sa InsertEndChild
00594     */
00595     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00596 
00597     /** Add a new node related to this. Adds a child before the specified child.
00598         Returns a pointer to the new object or NULL if an error occured.
00599     */
00600     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00601 
00602     /** Add a new node related to this. Adds a child after the specified child.
00603         Returns a pointer to the new object or NULL if an error occured.
00604     */
00605     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
00606 
00607     /** Replace a child of this node.
00608         Returns a pointer to the new object or NULL if an error occured.
00609     */
00610     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00611 
00612     /// Delete a child of this node.
00613     bool RemoveChild( TiXmlNode* removeThis );
00614 
00615     /// Navigate to a sibling node.
00616     const TiXmlNode* PreviousSibling() const            { return prev; }
00617     TiXmlNode* PreviousSibling()                        { return prev; }
00618 
00619     /// Navigate to a sibling node.
00620     const TiXmlNode* PreviousSibling( const char * ) const;
00621     TiXmlNode* PreviousSibling( const char *_prev ) {
00622         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
00623     }
00624 
00625     #ifdef TIXML_USE_STL
00626     const TiXmlNode* PreviousSibling( const std::string& _value ) const    {    return PreviousSibling (_value.c_str ());    }    ///< STL std::string form.
00627     TiXmlNode* PreviousSibling( const std::string& _value )             {    return PreviousSibling (_value.c_str ());    }    ///< STL std::string form.
00628     const TiXmlNode* NextSibling( const std::string& _value) const        {    return NextSibling (_value.c_str ());    }    ///< STL std::string form.
00629     TiXmlNode* NextSibling( const std::string& _value)                     {    return NextSibling (_value.c_str ());    }    ///< STL std::string form.
00630     #endif
00631 
00632     /// Navigate to a sibling node.
00633     const TiXmlNode* NextSibling() const                { return next; }
00634     TiXmlNode* NextSibling()                            { return next; }
00635 
00636     /// Navigate to a sibling node with the given 'value'.
00637     const TiXmlNode* NextSibling( const char * ) const;
00638     TiXmlNode* NextSibling( const char* _next ) {
00639         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
00640     }
00641 
00642     /** Convenience function to get through elements.
00643         Calls NextSibling and ToElement. Will skip all non-Element
00644         nodes. Returns 0 if there is not another element.
00645     */
00646     const TiXmlElement* NextSiblingElement() const;
00647     TiXmlElement* NextSiblingElement() {
00648         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
00649     }
00650 
00651     /** Convenience function to get through elements.
00652         Calls NextSibling and ToElement. Will skip all non-Element
00653         nodes. Returns 0 if there is not another element.
00654     */
00655     const TiXmlElement* NextSiblingElement( const char * ) const;
00656     TiXmlElement* NextSiblingElement( const char *_next ) {
00657         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
00658     }
00659 
00660     #ifdef TIXML_USE_STL
00661     const TiXmlElement* NextSiblingElement( const std::string& _value) const    {    return NextSiblingElement (_value.c_str ());    }    ///< STL std::string form.
00662     TiXmlElement* NextSiblingElement( const std::string& _value)                {    return NextSiblingElement (_value.c_str ());    }    ///< STL std::string form.
00663     #endif
00664 
00665     /// Convenience function to get through elements.
00666     const TiXmlElement* FirstChildElement()    const;
00667     TiXmlElement* FirstChildElement() {
00668         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
00669     }
00670 
00671     /// Convenience function to get through elements.
00672     const TiXmlElement* FirstChildElement( const char * _value ) const;
00673     TiXmlElement* FirstChildElement( const char * _value ) {
00674         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
00675     }
00676 
00677     #ifdef TIXML_USE_STL
00678     const TiXmlElement* FirstChildElement( const std::string& _value ) const    {    return FirstChildElement (_value.c_str ());    }    ///< STL std::string form.
00679     TiXmlElement* FirstChildElement( const std::string& _value )                {    return FirstChildElement (_value.c_str ());    }    ///< STL std::string form.
00680     #endif
00681 
00682     /** Query the type (as an enumerated value, above) of this node.
00683         The possible types are: DOCUMENT, ELEMENT, COMMENT,
00684                                 UNKNOWN, TEXT, and DECLARATION.
00685     */
00686     int Type() const    { return type; }
00687 
00688     /** Return a pointer to the Document this node lives in.
00689         Returns null if not in a document.
00690     */
00691     const TiXmlDocument* GetDocument() const;
00692     TiXmlDocument* GetDocument() {
00693         return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
00694     }
00695 
00696     /// Returns true if this node has no children.
00697     bool NoChildren() const                        { return !firstChild; }
00698 
00699     virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00700     virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00701     virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00702     virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00703     virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00704     virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00705 
00706     virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00707     virtual TiXmlElement*           ToElement()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00708     virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00709     virtual TiXmlUnknown*           ToUnknown()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00710     virtual TiXmlText*                ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00711     virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00712 
00713     /** Create an exact duplicate of this node and return it. The memory must be deleted
00714         by the caller. 
00715     */
00716     virtual TiXmlNode* Clone() const = 0;
00717 
00718     /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the 
00719         XML tree will be conditionally visited and the host will be called back
00720         via the TiXmlVisitor interface.
00721 
00722         This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
00723         the XML for the callbacks, so the performance of TinyXML is unchanged by using this
00724         interface versus any other.)
00725 
00726         The interface has been based on ideas from:
00727 
00728         - http://www.saxproject.org/
00729         - http://c2.com/cgi/wiki?HierarchicalVisitorPattern 
00730 
00731         Which are both good references for "visiting".
00732 
00733         An example of using Accept():
00734         @verbatim
00735         TiXmlPrinter printer;
00736         tinyxmlDoc.Accept( &printer );
00737         const char* xmlcstr = printer.CStr();
00738         @endverbatim
00739     */
00740     virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
00741 
00742 protected:
00743     TiXmlNode( NodeType _type );
00744 
00745     // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
00746     // and the assignment operator.
00747     void CopyTo( TiXmlNode* target ) const;
00748 
00749     #ifdef TIXML_USE_STL
00750         // The real work of the input operator.
00751     virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
00752     #endif
00753 
00754     // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
00755     TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
00756 
00757     TiXmlNode*        parent;
00758     NodeType        type;
00759 
00760     TiXmlNode*        firstChild;
00761     TiXmlNode*        lastChild;
00762 
00763     TIXML_STRING    value;
00764 
00765     TiXmlNode*        prev;
00766     TiXmlNode*        next;
00767 
00768 private:
00769     TiXmlNode( const TiXmlNode& );                // not implemented.
00770     void operator=( const TiXmlNode& base );    // not allowed.
00771 };
00772 
00773 
00774 /** An attribute is a name-value pair. Elements have an arbitrary
00775     number of attributes, each with a unique name.
00776 
00777     @note The attributes are not TiXmlNodes, since they are not
00778           part of the tinyXML document object model. There are other
00779           suggested ways to look at this problem.
00780 */
00781 class TiXmlAttribute : public TiXmlBase
00782 {
00783     friend class TiXmlAttributeSet;
00784 
00785 public:
00786     /// Construct an empty attribute.
00787     TiXmlAttribute() : TiXmlBase()
00788     {
00789         document = 0;
00790         prev = next = 0;
00791     }
00792 
00793     #ifdef TIXML_USE_STL
00794     /// std::string constructor.
00795     TiXmlAttribute( const std::string& _name, const std::string& _value )
00796     {
00797         name = _name;
00798         value = _value;
00799         document = 0;
00800         prev = next = 0;
00801     }
00802     #endif
00803 
00804     /// Construct an attribute with a name and value.
00805     TiXmlAttribute( const char * _name, const char * _value )
00806     {
00807         name = _name;
00808         value = _value;
00809         document = 0;
00810         prev = next = 0;
00811     }
00812 
00813     const char*        Name()  const        { return name.c_str(); }        ///< Return the name of this attribute.
00814     const char*        Value() const        { return value.c_str(); }        ///< Return the value of this attribute.
00815     #ifdef TIXML_USE_STL
00816     const std::string& ValueStr() const    { return value; }                ///< Return the value of this attribute.
00817     #endif
00818     int                IntValue() const;                                    ///< Return the value of this attribute, converted to an integer.
00819     double            DoubleValue() const;                                ///< Return the value of this attribute, converted to a double.
00820 
00821     // Get the tinyxml string representation
00822     const TIXML_STRING& NameTStr() const { return name; }
00823 
00824     /** QueryIntValue examines the value string. It is an alternative to the
00825         IntValue() method with richer error checking.
00826         If the value is an integer, it is stored in 'value' and 
00827         the call returns TIXML_SUCCESS. If it is not
00828         an integer, it returns TIXML_WRONG_TYPE.
00829 
00830         A specialized but useful call. Note that for success it returns 0,
00831         which is the opposite of almost all other TinyXml calls.
00832     */
00833     int QueryIntValue( int* _value ) const;
00834     /// QueryDoubleValue examines the value string. See QueryIntValue().
00835     int QueryDoubleValue( double* _value ) const;
00836 
00837     void SetName( const char* _name )    { name = _name; }                ///< Set the name of this attribute.
00838     void SetValue( const char* _value )    { value = _value; }                ///< Set the value.
00839 
00840     void SetIntValue( int _value );                                        ///< Set the value from an integer.
00841     void SetDoubleValue( double _value );                                ///< Set the value from a double.
00842 
00843     #ifdef TIXML_USE_STL
00844     /// STL std::string form.
00845     void SetName( const std::string& _name )    { name = _name; }    
00846     /// STL std::string form.    
00847     void SetValue( const std::string& _value )    { value = _value; }
00848     #endif
00849 
00850     /// Get the next sibling attribute in the DOM. Returns null at end.
00851     const TiXmlAttribute* Next() const;
00852     TiXmlAttribute* Next() {
00853         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
00854     }
00855 
00856     /// Get the previous sibling attribute in the DOM. Returns null at beginning.
00857     const TiXmlAttribute* Previous() const;
00858     TiXmlAttribute* Previous() {
00859         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
00860     }
00861 
00862     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00863     bool operator<( const TiXmlAttribute& rhs )     const { return name < rhs.name; }
00864     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
00865 
00866     /*    Attribute parsing starts: first letter of the name
00867                          returns: the next char after the value end quote
00868     */
00869     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
00870 
00871     // Prints this Attribute to a FILE stream.
00872     virtual void Print( FILE* cfile, int depth ) const {
00873         Print( cfile, depth, 0 );
00874     }
00875     void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
00876 
00877     // [internal use]
00878     // Set the document pointer so the attribute can report errors.
00879     void SetDocument( TiXmlDocument* doc )    { document = doc; }
00880 
00881 private:
00882     TiXmlAttribute( const TiXmlAttribute& );                // not implemented.
00883     void operator=( const TiXmlAttribute& base );    // not allowed.
00884 
00885     TiXmlDocument*    document;    // A pointer back to a document, for error reporting.
00886     TIXML_STRING name;
00887     TIXML_STRING value;
00888     TiXmlAttribute*    prev;
00889     TiXmlAttribute*    next;
00890 };
00891 
00892 
00893 /*    A class used to manage a group of attributes.
00894     It is only used internally, both by the ELEMENT and the DECLARATION.
00895     
00896     The set can be changed transparent to the Element and Declaration
00897     classes that use it, but NOT transparent to the Attribute
00898     which has to implement a next() and previous() method. Which makes
00899     it a bit problematic and prevents the use of STL.
00900 
00901     This version is implemented with circular lists because:
00902         - I like circular lists
00903         - it demonstrates some independence from the (typical) doubly linked list.
00904 */
00905 class TiXmlAttributeSet
00906 {
00907 public:
00908     TiXmlAttributeSet();
00909     ~TiXmlAttributeSet();
00910 
00911     void Add( TiXmlAttribute* attribute );
00912     void Remove( TiXmlAttribute* attribute );
00913 
00914     const TiXmlAttribute* First()    const    { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00915     TiXmlAttribute* First()                    { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00916     const TiXmlAttribute* Last() const        { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00917     TiXmlAttribute* Last()                    { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00918 
00919     TiXmlAttribute*    Find( const char* _name ) const;
00920     TiXmlAttribute* FindOrCreate( const char* _name );
00921 
00922 #    ifdef TIXML_USE_STL
00923     TiXmlAttribute*    Find( const std::string& _name ) const;
00924     TiXmlAttribute* FindOrCreate( const std::string& _name );
00925 #    endif
00926 
00927 
00928 private:
00929     //*ME:    Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
00930     //*ME:    this class must be also use a hidden/disabled copy-constructor !!!
00931     TiXmlAttributeSet( const TiXmlAttributeSet& );    // not allowed
00932     void operator=( const TiXmlAttributeSet& );    // not allowed (as TiXmlAttribute)
00933 
00934     TiXmlAttribute sentinel;
00935 };
00936 
00937 
00938 /** The element is a container class. It has a value, the element name,
00939     and can contain other elements, text, comments, and unknowns.
00940     Elements also contain an arbitrary number of attributes.
00941 */
00942 class TiXmlElement : public TiXmlNode
00943 {
00944 public:
00945     /// Construct an element.
00946     TiXmlElement (const char * in_value);
00947 
00948     #ifdef TIXML_USE_STL
00949     /// std::string constructor.
00950     TiXmlElement( const std::string& _value );
00951     #endif
00952 
00953     TiXmlElement( const TiXmlElement& );
00954 
00955     void operator=( const TiXmlElement& base );
00956 
00957     virtual ~TiXmlElement();
00958 
00959     /** Given an attribute name, Attribute() returns the value
00960         for the attribute of that name, or null if none exists.
00961     */
00962     const char* Attribute( const char* name ) const;
00963 
00964     /** Given an attribute name, Attribute() returns the value
00965         for the attribute of that name, or null if none exists.
00966         If the attribute exists and can be converted to an integer,
00967         the integer value will be put in the return 'i', if 'i'
00968         is non-null.
00969     */
00970     const char* Attribute( const char* name, int* i ) const;
00971 
00972     /** Given an attribute name, Attribute() returns the value
00973         for the attribute of that name, or null if none exists.
00974         If the attribute exists and can be converted to an double,
00975         the double value will be put in the return 'd', if 'd'
00976         is non-null.
00977     */
00978     const char* Attribute( const char* name, double* d ) const;
00979 
00980     /** QueryIntAttribute examines the attribute - it is an alternative to the
00981         Attribute() method with richer error checking.
00982         If the attribute is an integer, it is stored in 'value' and 
00983         the call returns TIXML_SUCCESS. If it is not
00984         an integer, it returns TIXML_WRONG_TYPE. If the attribute
00985         does not exist, then TIXML_NO_ATTRIBUTE is returned.
00986     */    
00987     int QueryIntAttribute( const char* name, int* _value ) const;
00988     /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
00989     int QueryDoubleAttribute( const char* name, double* _value ) const;
00990     /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
00991     int QueryFloatAttribute( const char* name, float* _value ) const {
00992         double d;
00993         int result = QueryDoubleAttribute( name, &d );
00994         if ( result == TIXML_SUCCESS ) {
00995             *_value = (float)d;
00996         }
00997         return result;
00998     }
00999 
01000     #ifdef TIXML_USE_STL
01001     /// QueryStringAttribute examines the attribute - see QueryIntAttribute().
01002     int QueryStringAttribute( const char* name, std::string* _value ) const {
01003         const char* cstr = Attribute( name );
01004         if ( cstr ) {
01005             *_value = std::string( cstr );
01006             return TIXML_SUCCESS;
01007         }
01008         return TIXML_NO_ATTRIBUTE;
01009     }
01010 
01011     /** Template form of the attribute query which will try to read the
01012         attribute into the specified type. Very easy, very powerful, but
01013         be careful to make sure to call this with the correct type.
01014         
01015         NOTE: This method doesn't work correctly for 'string' types that contain spaces.
01016 
01017         @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
01018     */
01019     template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
01020     {
01021         const TiXmlAttribute* node = attributeSet.Find( name );
01022         if ( !node )
01023             return TIXML_NO_ATTRIBUTE;
01024 
01025         std::stringstream sstream( node->ValueStr() );
01026         sstream >> *outValue;
01027         if ( !sstream.fail() )
01028             return TIXML_SUCCESS;
01029         return TIXML_WRONG_TYPE;
01030     }
01031 
01032     int QueryValueAttribute( const std::string& name, std::string* outValue ) const
01033     {
01034         const TiXmlAttribute* node = attributeSet.Find( name );
01035         if ( !node )
01036             return TIXML_NO_ATTRIBUTE;
01037         *outValue = node->ValueStr();
01038         return TIXML_SUCCESS;
01039     }
01040     #endif
01041 
01042     /** Sets an attribute of name to a given value. The attribute
01043         will be created if it does not exist, or changed if it does.
01044     */
01045     void SetAttribute( const char* name, const char * _value );
01046 
01047     #ifdef TIXML_USE_STL
01048     const std::string* Attribute( const std::string& name ) const;
01049     const std::string* Attribute( const std::string& name, int* i ) const;
01050     const std::string* Attribute( const std::string& name, double* d ) const;
01051     int QueryIntAttribute( const std::string& name, int* _value ) const;
01052     int QueryDoubleAttribute( const std::string& name, double* _value ) const;
01053 
01054     /// STL std::string form.
01055     void SetAttribute( const std::string& name, const std::string& _value );
01056     ///< STL std::string form.
01057     void SetAttribute( const std::string& name, int _value );
01058     ///< STL std::string form.
01059     void SetDoubleAttribute( const std::string& name, double value );
01060     #endif
01061 
01062     /** Sets an attribute of name to a given value. The attribute
01063         will be created if it does not exist, or changed if it does.
01064     */
01065     void SetAttribute( const char * name, int value );
01066 
01067     /** Sets an attribute of name to a given value. The attribute
01068         will be created if it does not exist, or changed if it does.
01069     */
01070     void SetDoubleAttribute( const char * name, double value );
01071 
01072     /** Deletes an attribute with the given name.
01073     */
01074     void RemoveAttribute( const char * name );
01075     #ifdef TIXML_USE_STL
01076     void RemoveAttribute( const std::string& name )    {    RemoveAttribute (name.c_str ());    }    ///< STL std::string form.
01077     #endif
01078 
01079     const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }        ///< Access the first attribute in this element.
01080     TiXmlAttribute* FirstAttribute()                 { return attributeSet.First(); }
01081     const TiXmlAttribute* LastAttribute()    const     { return attributeSet.Last(); }        ///< Access the last attribute in this element.
01082     TiXmlAttribute* LastAttribute()                    { return attributeSet.Last(); }
01083 
01084     /** Convenience function for easy access to the text inside an element. Although easy
01085         and concise, GetText() is limited compared to getting the TiXmlText child
01086         and accessing it directly.
01087     
01088         If the first child of 'this' is a TiXmlText, the GetText()
01089         returns the character string of the Text node, else null is returned.
01090 
01091         This is a convenient method for getting the text of simple contained text:
01092         @verbatim
01093         <foo>This is text</foo>
01094         const char* str = fooElement->GetText();
01095         @endverbatim
01096 
01097         'str' will be a pointer to "This is text". 
01098         
01099         Note that this function can be misleading. If the element foo was created from
01100         this XML:
01101         @verbatim
01102         <foo><b>This is text</b></foo> 
01103         @endverbatim
01104 
01105         then the value of str would be null. The first child node isn't a text node, it is
01106         another element. From this XML:
01107         @verbatim
01108         <foo>This is <b>text</b></foo> 
01109         @endverbatim
01110         GetText() will return "This is ".
01111 
01112         WARNING: GetText() accesses a child node - don't become confused with the 
01113                  similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
01114                  safe type casts on the referenced node.
01115     */
01116     const char* GetText() const;
01117 
01118     /// Creates a new Element and returns it - the returned element is a copy.
01119     virtual TiXmlNode* Clone() const;
01120     // Print the Element to a FILE stream.
01121     virtual void Print( FILE* cfile, int depth ) const;
01122 
01123     /*    Attribtue parsing starts: next char past '<'
01124                          returns: next char past '>'
01125     */
01126     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01127 
01128     virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01129     virtual TiXmlElement*           ToElement()              { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01130 
01131     /** Walk the XML tree visiting this node and all of its children. 
01132     */
01133     virtual bool Accept( TiXmlVisitor* visitor ) const;
01134 
01135 protected:
01136 
01137     void CopyTo( TiXmlElement* target ) const;
01138     void ClearThis();    // like clear, but initializes 'this' object as well
01139 
01140     // Used to be public [internal use]
01141     #ifdef TIXML_USE_STL
01142     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01143     #endif
01144     /*    [internal use]
01145         Reads the "value" of the element -- another element, or text.
01146         This should terminate with the current end tag.
01147     */
01148     const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01149 
01150 private:
01151     TiXmlAttributeSet attributeSet;
01152 };
01153 
01154 
01155 /**    An XML comment.
01156 */
01157 class TiXmlComment : public TiXmlNode
01158 {
01159 public:
01160     /// Constructs an empty comment.
01161     TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
01162     /// Construct a comment from text.
01163     TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
01164         SetValue( _value );
01165     }
01166     TiXmlComment( const TiXmlComment& );
01167     void operator=( const TiXmlComment& base );
01168 
01169     virtual ~TiXmlComment()    {}
01170 
01171     /// Returns a copy of this Comment.
01172     virtual TiXmlNode* Clone() const;
01173     // Write this Comment to a FILE stream.
01174     virtual void Print( FILE* cfile, int depth ) const;
01175 
01176     /*    Attribtue parsing starts: at the ! of the !--
01177                          returns: next char past '>'
01178     */
01179     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01180 
01181     virtual const TiXmlComment*  ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01182     virtual TiXmlComment*  ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01183 
01184     /** Walk the XML tree visiting this node and all of its children. 
01185     */
01186     virtual bool Accept( TiXmlVisitor* visitor ) const;
01187 
01188 protected:
01189     void CopyTo( TiXmlComment* target ) const;
01190 
01191     // used to be public
01192     #ifdef TIXML_USE_STL
01193     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01194     #endif
01195 //    virtual void StreamOut( TIXML_OSTREAM * out ) const;
01196 
01197 private:
01198 
01199 };
01200 
01201 
01202 /** XML text. A text node can have 2 ways to output the next. "normal" output 
01203     and CDATA. It will default to the mode it was parsed from the XML file and
01204     you generally want to leave it alone, but you can change the output mode with 
01205     SetCDATA() and query it with CDATA().
01206 */
01207 class TiXmlText : public TiXmlNode
01208 {
01209     friend class TiXmlElement;
01210 public:
01211     /** Constructor for text element. By default, it is treated as 
01212         normal, encoded text. If you want it be output as a CDATA text
01213         element, set the parameter _cdata to 'true'
01214     */
01215     TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
01216     {
01217         SetValue( initValue );
01218         cdata = false;
01219     }
01220     virtual ~TiXmlText() {}
01221 
01222     #ifdef TIXML_USE_STL
01223     /// Constructor.
01224     TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
01225     {
01226         SetValue( initValue );
01227         cdata = false;
01228     }
01229     #endif
01230 
01231     TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT )    { copy.CopyTo( this ); }
01232     void operator=( const TiXmlText& base )                                 { base.CopyTo( this ); }
01233 
01234     // Write this text object to a FILE stream.
01235     virtual void Print( FILE* cfile, int depth ) const;
01236 
01237     /// Queries whether this represents text using a CDATA section.
01238     bool CDATA() const                { return cdata; }
01239     /// Turns on or off a CDATA representation of text.
01240     void SetCDATA( bool _cdata )    { cdata = _cdata; }
01241 
01242     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01243 
01244     virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01245     virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01246 
01247     /** Walk the XML tree visiting this node and all of its children. 
01248     */
01249     virtual bool Accept( TiXmlVisitor* content ) const;
01250 
01251 protected :
01252     ///  [internal use] Creates a new Element and returns it.
01253     virtual TiXmlNode* Clone() const;
01254     void CopyTo( TiXmlText* target ) const;
01255 
01256     bool Blank() const;    // returns true if all white space and new lines
01257     // [internal use]
01258     #ifdef TIXML_USE_STL
01259     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01260     #endif
01261 
01262 private:
01263     bool cdata;            // true if this should be input and output as a CDATA style text element
01264 };
01265 
01266 
01267 /** In correct XML the declaration is the first entry in the file.
01268     @verbatim
01269         <?xml version="1.0" standalone="yes"?>
01270     @endverbatim
01271 
01272     TinyXml will happily read or write files without a declaration,
01273     however. There are 3 possible attributes to the declaration:
01274     version, encoding, and standalone.
01275 
01276     Note: In this version of the code, the attributes are
01277     handled as special cases, not generic attributes, simply
01278     because there can only be at most 3 and they are always the same.
01279 */
01280 class TiXmlDeclaration : public TiXmlNode
01281 {
01282 public:
01283     /// Construct an empty declaration.
01284     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
01285 
01286 #ifdef TIXML_USE_STL
01287     /// Constructor.
01288     TiXmlDeclaration(    const std::string& _version,
01289                         const std::string& _encoding,
01290                         const std::string& _standalone );
01291 #endif
01292 
01293     /// Construct.
01294     TiXmlDeclaration(    const char* _version,
01295                         const char* _encoding,
01296                         const char* _standalone );
01297 
01298     TiXmlDeclaration( const TiXmlDeclaration& copy );
01299     void operator=( const TiXmlDeclaration& copy );
01300 
01301     virtual ~TiXmlDeclaration()    {}
01302 
01303     /// Version. Will return an empty string if none was found.
01304     const char *Version() const            { return version.c_str (); }
01305     /// Encoding. Will return an empty string if none was found.
01306     const char *Encoding() const        { return encoding.c_str (); }
01307     /// Is this a standalone document?
01308     const char *Standalone() const        { return standalone.c_str (); }
01309 
01310     /// Creates a copy of this Declaration and returns it.
01311     virtual TiXmlNode* Clone() const;
01312     // Print this declaration to a FILE stream.
01313     virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
01314     virtual void Print( FILE* cfile, int depth ) const {
01315         Print( cfile, depth, 0 );
01316     }
01317 
01318     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01319 
01320     virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01321     virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01322 
01323     /** Walk the XML tree visiting this node and all of its children. 
01324     */
01325     virtual bool Accept( TiXmlVisitor* visitor ) const;
01326 
01327 protected:
01328     void CopyTo( TiXmlDeclaration* target ) const;
01329     // used to be public
01330     #ifdef TIXML_USE_STL
01331     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01332     #endif
01333 
01334 private:
01335 
01336     TIXML_STRING version;
01337     TIXML_STRING encoding;
01338     TIXML_STRING standalone;
01339 };
01340 
01341 
01342 /** Any tag that tinyXml doesn't recognize is saved as an
01343     unknown. It is a tag of text, but should not be modified.
01344     It will be written back to the XML, unchanged, when the file
01345     is saved.
01346 
01347     DTD tags get thrown into TiXmlUnknowns.
01348 */
01349 class TiXmlUnknown : public TiXmlNode
01350 {
01351 public:
01352     TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )    {}
01353     virtual ~TiXmlUnknown() {}
01354 
01355     TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )        { copy.CopyTo( this ); }
01356     void operator=( const TiXmlUnknown& copy )                                        { copy.CopyTo( this ); }
01357 
01358     /// Creates a copy of this Unknown and returns it.
01359     virtual TiXmlNode* Clone() const;
01360     // Print this Unknown to a FILE stream.
01361     virtual void Print( FILE* cfile, int depth ) const;
01362 
01363     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01364 
01365     virtual const TiXmlUnknown*     ToUnknown()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01366     virtual TiXmlUnknown*           ToUnknown()        { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01367 
01368     /** Walk the XML tree visiting this node and all of its children. 
01369     */
01370     virtual bool Accept( TiXmlVisitor* content ) const;
01371 
01372 protected:
01373     void CopyTo( TiXmlUnknown* target ) const;
01374 
01375     #ifdef TIXML_USE_STL
01376     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01377     #endif
01378 
01379 private:
01380 
01381 };
01382 
01383 
01384 /** Always the top level node. A document binds together all the
01385     XML pieces. It can be saved, loaded, and printed to the screen.
01386     The 'value' of a document node is the xml file name.
01387 */
01388 class TiXmlDocument : public TiXmlNode
01389 {
01390 public:
01391     /// Create an empty document, that has no name.
01392     TiXmlDocument();
01393     /// Create a document with a name. The name of the document is also the filename of the xml.
01394     TiXmlDocument( const char * documentName );
01395 
01396     #ifdef TIXML_USE_STL
01397     /// Constructor.
01398     TiXmlDocument( const std::string& documentName );
01399     #endif
01400 
01401     TiXmlDocument( const TiXmlDocument& copy );
01402     void operator=( const TiXmlDocument& copy );
01403 
01404     virtual ~TiXmlDocument() {}
01405 
01406     /** Load a file using the current document value.
01407         Returns true if successful. Will delete any existing
01408         document data before loading.
01409     */
01410     bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01411     /// Save a file using the current document value. Returns true if successful.
01412     bool SaveFile() const;
01413     /// Load a file using the given filename. Returns true if successful.
01414     bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01415     /// Save a file using the given filename. Returns true if successful.
01416     bool SaveFile( const char * filename ) const;
01417     /** Load a file using the given FILE*. Returns true if successful. Note that this method
01418         doesn't stream - the entire object pointed at by the FILE*
01419         will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
01420         file location. Streaming may be added in the future.
01421     */
01422     bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01423     /// Save a file using the given FILE*. Returns true if successful.
01424     bool SaveFile( FILE* ) const;
01425 
01426     #ifdef TIXML_USE_STL
01427     bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )            ///< STL std::string version.
01428     {
01429         return LoadFile( filename.c_str(), encoding );
01430     }
01431     bool SaveFile( const std::string& filename ) const        ///< STL std::string version.
01432     {
01433         return SaveFile( filename.c_str() );
01434     }
01435     #endif
01436 
01437     /** Parse the given null terminated block of xml data. Passing in an encoding to this
01438         method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
01439         to use that encoding, regardless of what TinyXml might otherwise try to detect.
01440     */
01441     virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01442 
01443     /** Get the root element -- the only top level element -- of the document.
01444         In well formed XML, there should only be one. TinyXml is tolerant of
01445         multiple elements at the document level.
01446     */
01447     const TiXmlElement* RootElement() const        { return FirstChildElement(); }
01448     TiXmlElement* RootElement()                    { return FirstChildElement(); }
01449 
01450     /** If an error occurs, Error will be set to true. Also,
01451         - The ErrorId() will contain the integer identifier of the error (not generally useful)
01452         - The ErrorDesc() method will return the name of the error. (very useful)
01453         - The ErrorRow() and ErrorCol() will return the location of the error (if known)
01454     */    
01455     bool Error() const                        { return error; }
01456 
01457     /// Contains a textual (english) description of the error if one occurs.
01458     const char * ErrorDesc() const    { return errorDesc.c_str (); }
01459 
01460     /** Generally, you probably want the error string ( ErrorDesc() ). But if you
01461         prefer the ErrorId, this function will fetch it.
01462     */
01463     int ErrorId()    const                { return errorId; }
01464 
01465     /** Returns the location (if known) of the error. The first column is column 1, 
01466         and the first row is row 1. A value of 0 means the row and column wasn't applicable
01467         (memory errors, for example, have no row/column) or the parser lost the error. (An
01468         error in the error reporting, in that case.)
01469 
01470         @sa SetTabSize, Row, Column
01471     */
01472     int ErrorRow() const    { return errorLocation.row+1; }
01473     int ErrorCol() const    { return errorLocation.col+1; }    ///< The column where the error occured. See ErrorRow()
01474 
01475     /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
01476         to report the correct values for row and column. It does not change the output
01477         or input in any way.
01478         
01479         By calling this method, with a tab size
01480         greater than 0, the row and column of each node and attribute is stored
01481         when the file is loaded. Very useful for tracking the DOM back in to
01482         the source file.
01483 
01484         The tab size is required for calculating the location of nodes. If not
01485         set, the default of 4 is used. The tabsize is set per document. Setting
01486         the tabsize to 0 disables row/column tracking.
01487 
01488         Note that row and column tracking is not supported when using operator>>.
01489 
01490         The tab size needs to be enabled before the parse or load. Correct usage:
01491         @verbatim
01492         TiXmlDocument doc;
01493         doc.SetTabSize( 8 );
01494         doc.Load( "myfile.xml" );
01495         @endverbatim
01496 
01497         @sa Row, Column
01498     */
01499     void SetTabSize( int _tabsize )        { tabsize = _tabsize; }
01500 
01501     int TabSize() const    { return tabsize; }
01502 
01503     /** If you have handled the error, it can be reset with this call. The error
01504         state is automatically cleared if you Parse a new XML block.
01505     */
01506     void ClearError()                        {    error = false; 
01507                                                 errorId = 0; 
01508                                                 errorDesc = ""; 
01509                                                 errorLocation.row = errorLocation.col = 0; 
01510                                                 //errorLocation.last = 0; 
01511                                             }
01512 
01513     /** Write the document to standard out using formatted printing ("pretty print"). */
01514     void Print() const                        { Print( stdout, 0 ); }
01515 
01516     /* Write the document to a string using formatted printing ("pretty print"). This
01517         will allocate a character array (new char[]) and return it as a pointer. The
01518         calling code pust call delete[] on the return char* to avoid a memory leak.
01519     */
01520     //char* PrintToMemory() const; 
01521 
01522     /// Print this Document to a FILE stream.
01523     virtual void Print( FILE* cfile, int depth = 0 ) const;
01524     // [internal use]
01525     void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01526 
01527     virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01528     virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01529 
01530     /** Walk the XML tree visiting this node and all of its children. 
01531     */
01532     virtual bool Accept( TiXmlVisitor* content ) const;
01533 
01534 protected :
01535     // [internal use]
01536     virtual TiXmlNode* Clone() const;
01537     #ifdef TIXML_USE_STL
01538     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01539     #endif
01540 
01541 private:
01542     void CopyTo( TiXmlDocument* target ) const;
01543 
01544     bool error;
01545     int  errorId;
01546     TIXML_STRING errorDesc;
01547     int tabsize;
01548     TiXmlCursor errorLocation;
01549     bool useMicrosoftBOM;        // the UTF-8 BOM were found when read. Note this, and try to write.
01550 };
01551 
01552 
01553 /**
01554     A TiXmlHandle is a class that wraps a node pointer with null checks; this is
01555     an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
01556     DOM structure. It is a separate utility class.
01557 
01558     Take an example:
01559     @verbatim
01560     <Document>
01561         <Element attributeA = "valueA">
01562             <Child attributeB = "value1" />
01563             <Child attributeB = "value2" />
01564         </Element>
01565     <Document>
01566     @endverbatim
01567 
01568     Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
01569     easy to write a *lot* of code that looks like:
01570 
01571     @verbatim
01572     TiXmlElement* root = document.FirstChildElement( "Document" );
01573     if ( root )
01574     {
01575         TiXmlElement* element = root->FirstChildElement( "Element" );
01576         if ( element )
01577         {
01578             TiXmlElement* child = element->FirstChildElement( "Child" );
01579             if ( child )
01580             {
01581                 TiXmlElement* child2 = child->NextSiblingElement( "Child" );
01582                 if ( child2 )
01583                 {
01584                     // Finally do something useful.
01585     @endverbatim
01586 
01587     And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
01588     of such code. A TiXmlHandle checks for null    pointers so it is perfectly safe 
01589     and correct to use:
01590 
01591     @verbatim
01592     TiXmlHandle docHandle( &document );
01593     TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
01594     if ( child2 )
01595     {
01596         // do something useful
01597     @endverbatim
01598 
01599     Which is MUCH more concise and useful.
01600 
01601     It is also safe to copy handles - internally they are nothing more than node pointers.
01602     @verbatim
01603     TiXmlHandle handleCopy = handle;
01604     @endverbatim
01605 
01606     What they should not be used for is iteration:
01607 
01608     @verbatim
01609     int i=0; 
01610     while ( true )
01611     {
01612         TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
01613         if ( !child )
01614             break;
01615         // do something
01616         ++i;
01617     }
01618     @endverbatim
01619 
01620     It seems reasonable, but it is in fact two embedded while loops. The Child method is 
01621     a linear walk to find the element, so this code would iterate much more than it needs 
01622     to. Instead, prefer:
01623 
01624     @verbatim
01625     TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
01626 
01627     for( child; child; child=child->NextSiblingElement() )
01628     {
01629         // do something
01630     }
01631     @endverbatim
01632 */
01633 class TiXmlHandle
01634 {
01635 public:
01636     /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
01637     TiXmlHandle( TiXmlNode* _node )                    { this->node = _node; }
01638     /// Copy constructor
01639     TiXmlHandle( const TiXmlHandle& ref )            { this->node = ref.node; }
01640     TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
01641 
01642     /// Return a handle to the first child node.
01643     TiXmlHandle FirstChild() const;
01644     /// Return a handle to the first child node with the given name.
01645     TiXmlHandle FirstChild( const char * value ) const;
01646     /// Return a handle to the first child element.
01647     TiXmlHandle FirstChildElement() const;
01648     /// Return a handle to the first child element with the given name.
01649     TiXmlHandle FirstChildElement( const char * value ) const;
01650 
01651     /** Return a handle to the "index" child with the given name. 
01652         The first child is 0, the second 1, etc.
01653     */
01654     TiXmlHandle Child( const char* value, int index ) const;
01655     /** Return a handle to the "index" child. 
01656         The first child is 0, the second 1, etc.
01657     */
01658     TiXmlHandle Child( int index ) const;
01659     /** Return a handle to the "index" child element with the given name. 
01660         The first child element is 0, the second 1, etc. Note that only TiXmlElements
01661         are indexed: other types are not counted.
01662     */
01663     TiXmlHandle ChildElement( const char* value, int index ) const;
01664     /** Return a handle to the "index" child element. 
01665         The first child element is 0, the second 1, etc. Note that only TiXmlElements
01666         are indexed: other types are not counted.
01667     */
01668     TiXmlHandle ChildElement( int index ) const;
01669 
01670     #ifdef TIXML_USE_STL
01671     TiXmlHandle FirstChild( const std::string& _value ) const                { return FirstChild( _value.c_str() ); }
01672     TiXmlHandle FirstChildElement( const std::string& _value ) const        { return FirstChildElement( _value.c_str() ); }
01673 
01674     TiXmlHandle Child( const std::string& _value, int index ) const            { return Child( _value.c_str(), index ); }
01675     TiXmlHandle ChildElement( const std::string& _value, int index ) const    { return ChildElement( _value.c_str(), index ); }
01676     #endif
01677 
01678     /** Return the handle as a TiXmlNode. This may return null.
01679     */
01680     TiXmlNode* ToNode() const            { return node; } 
01681     /** Return the handle as a TiXmlElement. This may return null.
01682     */
01683     TiXmlElement* ToElement() const        { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
01684     /**    Return the handle as a TiXmlText. This may return null.
01685     */
01686     TiXmlText* ToText() const            { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
01687     /** Return the handle as a TiXmlUnknown. This may return null.
01688     */
01689     TiXmlUnknown* ToUnknown() const        { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
01690 
01691     /** @deprecated use ToNode. 
01692         Return the handle as a TiXmlNode. This may return null.
01693     */
01694     TiXmlNode* Node () const            { return ToNode(); } 
01695     /** @deprecated use ToElement. 
01696         Return the handle as a TiXmlElement. This may return null.
01697     */
01698     TiXmlElement* Element () const    { return ToElement(); }
01699     /**    @deprecated use ToText()
01700         Return the handle as a TiXmlText. This may return null.
01701     */
01702     TiXmlText* Text () const            { return ToText(); }
01703     /** @deprecated use ToUnknown()
01704         Return the handle as a TiXmlUnknown. This may return null.
01705     */
01706     TiXmlUnknown* Unknown () const    { return ToUnknown(); }
01707 
01708 private:
01709     TiXmlNode* node;
01710 };
01711 
01712 
01713 /** Print to memory functionality. The TiXmlPrinter is useful when you need to:
01714 
01715     -# Print to memory (especially in non-STL mode)
01716     -# Control formatting (line endings, etc.)
01717 
01718     When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
01719     Before calling Accept() you can call methods to control the printing
01720     of the XML document. After TiXmlNode::Accept() is called, the printed document can
01721     be accessed via the CStr(), Str(), and Size() methods.
01722 
01723     TiXmlPrinter uses the Visitor API.
01724     @verbatim
01725     TiXmlPrinter printer;
01726     printer.SetIndent( "\t" );
01727 
01728     doc.Accept( &printer );
01729     fprintf( stdout, "%s", printer.CStr() );
01730     @endverbatim
01731 */
01732 class TiXmlPrinter : public TiXmlVisitor
01733 {
01734 public:
01735     TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
01736                      buffer(), indent( "    " ), lineBreak( "\n" ) {}
01737 
01738     virtual bool VisitEnter( const TiXmlDocument& doc );
01739     virtual bool VisitExit( const TiXmlDocument& doc );
01740 
01741     virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
01742     virtual bool VisitExit( const TiXmlElement& element );
01743 
01744     virtual bool Visit( const TiXmlDeclaration& declaration );
01745     virtual bool Visit( const TiXmlText& text );
01746     virtual bool Visit( const TiXmlComment& comment );
01747     virtual bool Visit( const TiXmlUnknown& unknown );
01748 
01749     /** Set the indent characters for printing. By default 4 spaces
01750         but tab (\t) is also useful, or null/empty string for no indentation.
01751     */
01752     void SetIndent( const char* _indent )            { indent = _indent ? _indent : "" ; }
01753     /// Query the indention string.
01754     const char* Indent()                            { return indent.c_str(); }
01755     /** Set the line breaking string. By default set to newline (\n). 
01756         Some operating systems prefer other characters, or can be
01757         set to the null/empty string for no indenation.
01758     */
01759     void SetLineBreak( const char* _lineBreak )        { lineBreak = _lineBreak ? _lineBreak : ""; }
01760     /// Query the current line breaking string.
01761     const char* LineBreak()                            { return lineBreak.c_str(); }
01762 
01763     /** Switch over to "stream printing" which is the most dense formatting without 
01764         linebreaks. Common when the XML is needed for network transmission.
01765     */
01766     void SetStreamPrinting()                        { indent = "";
01767                                                       lineBreak = "";
01768                                                     }    
01769     /// Return the result.
01770     const char* CStr()                                { return buffer.c_str(); }
01771     /// Return the length of the result string.
01772     size_t Size()                                    { return buffer.size(); }
01773 
01774     #ifdef TIXML_USE_STL
01775     /// Return the result.
01776     const std::string& Str()                        { return buffer; }
01777     #endif
01778 
01779 private:
01780     void DoIndent()    {
01781         for( int i=0; i<depth; ++i )
01782             buffer += indent;
01783     }
01784     void DoLineBreak() {
01785         buffer += lineBreak;
01786     }
01787 
01788     int depth;
01789     bool simpleTextPrint;
01790     TIXML_STRING buffer;
01791     TIXML_STRING indent;
01792     TIXML_STRING lineBreak;
01793 };
01794 
01795 
01796 #ifdef _MSC_VER
01797 #pragma warning( pop )
01798 #endif
01799 
01800 #endif