Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core4/src/tinyxml/tinyxml.h @ 4192

Last change on this file since 4192 was 2710, checked in by rgrieder, 16 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

  • Property svn:eol-style set to native
File size: 65.8 KB
Line 
1/*
2www.sourceforge.net/projects/tinyxml
3Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
4
5This software is provided 'as-is', without any express or implied
6warranty. In no event will the authors be held liable for any
7damages arising from the use of this software.
8
9Permission is granted to anyone to use this software for any
10purpose, including commercial applications, and to alter it and
11redistribute it freely, subject to the following restrictions:
12
131. The origin of this software must not be misrepresented; you must
14not claim that you wrote the original software. If you use this
15software in a product, an acknowledgment in the product documentation
16would be appreciated but is not required.
17
182. Altered source versions must be plainly marked as such, and
19must not be misrepresented as being the original software.
20
213. This notice may not be removed or altered from any source
22distribution.
23*/
24
25
26#ifndef TINYXML_INCLUDED
27#define TINYXML_INCLUDED
28
29#ifdef _MSC_VER
30#pragma warning( push )
31#pragma warning( disable : 4530 )
32#pragma warning( disable : 4786 )
33#endif
34
35#include <ctype.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <assert.h>
40
41// Help out windows:
42#if defined( _DEBUG ) && !defined( DEBUG )
43#define DEBUG
44#endif
45
46#ifdef TIXML_USE_TICPP
47        #ifndef TIXML_USE_STL
48                #define TIXML_USE_STL
49        #endif
50#endif
51
52#ifdef TIXML_USE_STL
53        #include <string>
54        #include <iostream>
55        #include <sstream>
56        #define TIXML_STRING            std::string
57#else
58        #include "tinystr.h"
59        #define TIXML_STRING            TiXmlString
60#endif
61
62// Deprecated library function hell. Compilers want to use the
63// new safe versions. This probably doesn't fully address the problem,
64// but it gets closer. There are too many compilers for me to fully
65// test. If you get compilation troubles, undefine TIXML_SAFE
66#define TIXML_SAFE
67
68#ifdef TIXML_SAFE
69        #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
70                // Microsoft visual studio, version 2005 and higher.
71                #define TIXML_SNPRINTF _snprintf_s
72                #define TIXML_SNSCANF  _snscanf_s
73                #define TIXML_SSCANF   sscanf_s
74        #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
75                // Microsoft visual studio, version 6 and higher.
76                //#pragma message( "Using _sn* functions." )
77                #define TIXML_SNPRINTF _snprintf
78                #define TIXML_SNSCANF  _snscanf
79                #define TIXML_SSCANF   sscanf
80        #elif defined(__GNUC__) && (__GNUC__ >= 3 )
81                // GCC version 3 and higher.s
82                //#warning( "Using sn* functions." )
83                #define TIXML_SNPRINTF snprintf
84                #define TIXML_SNSCANF  snscanf
85                #define TIXML_SSCANF   sscanf
86        #else
87                #define TIXML_SSCANF   sscanf
88        #endif
89#endif
90
91class TiXmlDocument;
92class TiXmlElement;
93class TiXmlComment;
94class TiXmlUnknown;
95class TiXmlAttribute;
96class TiXmlText;
97class TiXmlDeclaration;
98class TiXmlStylesheetReference;
99class TiXmlParsingData;
100
101const int TIXML_MAJOR_VERSION = 2;
102const int TIXML_MINOR_VERSION = 5;
103const int TIXML_PATCH_VERSION = 3;
104
105/*      Internal structure for tracking location of items
106        in the XML file.
107*/
108struct TiXmlCursor
109{
110        TiXmlCursor()           { Clear(); }
111        void Clear()            { row = col = -1; }
112
113        int row;        // 0 based.
114        int col;        // 0 based.
115};
116
117
118/**
119        If you call the Accept() method, it requires being passed a TiXmlVisitor
120        class to handle callbacks. For nodes that contain other nodes (Document, Element)
121        you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
122        are simple called with Visit().
123
124        If you return 'true' from a Visit method, recursive parsing will continue. If you return
125        false, <b>no children of this node or its sibilings</b> will be Visited.
126
127        All flavors of Visit methods have a default implementation that returns 'true' (continue
128        visiting). You need to only override methods that are interesting to you.
129
130        Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
131
132        You should never change the document from a callback.
133
134        @sa TiXmlNode::Accept()
135*/
136class TiXmlVisitor
137{
138public:
139        virtual ~TiXmlVisitor() {}
140
141        /// Visit a document.
142        virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )                 { return true; }
143        /// Visit a document.
144        virtual bool VisitExit( const TiXmlDocument& /*doc*/ )                  { return true; }
145
146        /// Visit an element.
147        virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )    { return true; }
148        /// Visit an element.
149        virtual bool VisitExit( const TiXmlElement& /*element*/ )               { return true; }
150
151        /// Visit a declaration
152        virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )   { return true; }
153        /// Visit a stylesheet reference
154        virtual bool Visit( const TiXmlStylesheetReference& /*stylesheet*/ )    { return true; }
155        /// Visit a text node
156        virtual bool Visit( const TiXmlText& /*text*/ )                                 { return true; }
157        /// Visit a comment node
158        virtual bool Visit( const TiXmlComment& /*comment*/ )                   { return true; }
159        /// Visit an unknow node
160        virtual bool Visit( const TiXmlUnknown& /*unknown*/ )                   { return true; }
161};
162
163// Only used by Attribute::Query functions
164enum
165{
166        TIXML_SUCCESS,
167        TIXML_NO_ATTRIBUTE,
168        TIXML_WRONG_TYPE
169};
170
171
172// Used by the parsing routines.
173enum TiXmlEncoding
174{
175        TIXML_ENCODING_UNKNOWN,
176        TIXML_ENCODING_UTF8,
177        TIXML_ENCODING_LEGACY
178};
179
180const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
181
182/** TiXmlBase is a base class for every class in TinyXml.
183        It does little except to establish that TinyXml classes
184        can be printed and provide some utility functions.
185
186        In XML, the document and elements can contain
187        other elements and other types of nodes.
188
189        @verbatim
190        A Document can contain: Element (container or leaf)
191                                                        Comment (leaf)
192                                                        Unknown (leaf)
193                                                        Declaration( leaf )
194
195        An Element can contain: Element (container or leaf)
196                                                        Text    (leaf)
197                                                        Attributes (not on tree)
198                                                        Comment (leaf)
199                                                        Unknown (leaf)
200
201        A Decleration contains: Attributes (not on tree)
202        @endverbatim
203*/
204#ifdef TIXML_USE_TICPP
205#include "ticpprc.h"
206class TiXmlBase : public TiCppRC
207#else
208class TiXmlBase
209#endif
210{
211        friend class TiXmlNode;
212        friend class TiXmlElement;
213        friend class TiXmlDocument;
214
215public:
216        TiXmlBase()     :       userData(0)             {}
217        virtual ~TiXmlBase()                    {}
218
219        /**     All TinyXml classes can print themselves to a filestream
220                or the string class (TiXmlString in non-STL mode, std::string
221                in STL mode.) Either or both cfile and str can be null.
222
223                This is a formatted print, and will insert
224                tabs and newlines.
225
226                (For an unformatted stream, use the << operator.)
227        */
228        virtual void Print( FILE* cfile, int depth ) const = 0;
229
230        /**     The world does not agree on whether white space should be kept or
231                not. In order to make everyone happy, these global, static functions
232                are provided to set whether or not TinyXml will condense all white space
233                into a single space or not. The default is to condense. Note changing this
234                value is not thread safe.
235        */
236        static void SetCondenseWhiteSpace( bool condense )              { condenseWhiteSpace = condense; }
237
238        /// Return the current white space setting.
239        static bool IsWhiteSpaceCondensed()                                             { return condenseWhiteSpace; }
240
241        /** Return the position, in the original source file, of this node or attribute.
242                The row and column are 1-based. (That is the first row and first column is
243                1,1). If the returns values are 0 or less, then the parser does not have
244                a row and column value.
245
246                Generally, the row and column value will be set when the TiXmlDocument::Load(),
247                TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
248                when the DOM was created from operator>>.
249
250                The values reflect the initial load. Once the DOM is modified programmatically
251                (by adding or changing nodes and attributes) the new values will NOT update to
252                reflect changes in the document.
253
254                There is a minor performance cost to computing the row and column. Computation
255                can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
256
257                @sa TiXmlDocument::SetTabSize()
258        */
259        int Row() const                 { return location.row + 1; }
260        int Column() const              { return location.col + 1; }    ///< See Row()
261
262        void  SetUserData( void* user )                 { userData = user; }    ///< Set a pointer to arbitrary user data.
263        void* GetUserData()                                             { return userData; }    ///< Get a pointer to arbitrary user data.
264        const void* GetUserData() const                 { return userData; }    ///< Get a pointer to arbitrary user data.
265
266        // Table that returs, for a given lead byte, the total number of bytes
267        // in the UTF-8 sequence.
268        static const int utf8ByteTable[256];
269
270        virtual const char* Parse(      const char* p,
271                                                                TiXmlParsingData* data,
272                                                                TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
273
274        /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
275                or they will be transformed into entities!
276        */
277        static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
278
279        enum
280        {
281                TIXML_NO_ERROR = 0,
282                TIXML_ERROR,
283                TIXML_ERROR_OPENING_FILE,
284                TIXML_ERROR_OUT_OF_MEMORY,
285                TIXML_ERROR_PARSING_ELEMENT,
286                TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
287                TIXML_ERROR_READING_ELEMENT_VALUE,
288                TIXML_ERROR_READING_ATTRIBUTES,
289                TIXML_ERROR_PARSING_EMPTY,
290                TIXML_ERROR_READING_END_TAG,
291                TIXML_ERROR_PARSING_UNKNOWN,
292                TIXML_ERROR_PARSING_COMMENT,
293                TIXML_ERROR_PARSING_DECLARATION,
294                TIXML_ERROR_DOCUMENT_EMPTY,
295                TIXML_ERROR_EMBEDDED_NULL,
296                TIXML_ERROR_PARSING_CDATA,
297                TIXML_ERROR_DOCUMENT_TOP_ONLY,
298
299                TIXML_ERROR_STRING_COUNT
300        };
301
302protected:
303
304        static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
305        inline static bool IsWhiteSpace( char c )
306        {
307                return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
308        }
309        inline static bool IsWhiteSpace( int c )
310        {
311                if ( c < 256 )
312                        return IsWhiteSpace( (char) c );
313                return false;   // Again, only truly correct for English/Latin...but usually works.
314        }
315
316        #ifdef TIXML_USE_STL
317        static bool     StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
318        static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
319        #endif
320
321        /*      Reads an XML name into the string provided. Returns
322                a pointer just past the last character of the name,
323                or 0 if the function has an error.
324        */
325        static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
326
327        /*      Reads text. Returns a pointer past the given end tag.
328                Wickedly complex options, but it keeps the (sensitive) code in one place.
329        */
330        static const char* ReadText(    const char* in,                         // where to start
331                                                                        TIXML_STRING* text,                     // the string read
332                                                                        bool ignoreWhiteSpace,          // whether to keep the white space
333                                                                        const char* endTag,                     // what ends this text
334                                                                        bool ignoreCase,                        // whether to ignore case in the end tag
335                                                                        TiXmlEncoding encoding );       // the current encoding
336
337        // If an entity has been found, transform it into a character.
338        static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
339
340        // Get a character, while interpreting entities.
341        // The length can be from 0 to 4 bytes.
342        inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
343        {
344                assert( p );
345                if ( encoding == TIXML_ENCODING_UTF8 )
346                {
347                        *length = utf8ByteTable[ *((const unsigned char*)p) ];
348                        assert( *length >= 0 && *length < 5 );
349                }
350                else
351                {
352                        *length = 1;
353                }
354
355                if ( *length == 1 )
356                {
357                        if ( *p == '&' )
358                                return GetEntity( p, _value, length, encoding );
359                        *_value = *p;
360                        return p+1;
361                }
362                else if ( *length )
363                {
364                        //strncpy( _value, p, *length );        // lots of compilers don't like this function (unsafe),
365                                                                                                // and the null terminator isn't needed
366                        for( int i=0; p[i] && i<*length; ++i ) {
367                                _value[i] = p[i];
368                        }
369                        return p + (*length);
370                }
371                else
372                {
373                        // Not valid text.
374                        return 0;
375                }
376        }
377
378        // Return true if the next characters in the stream are any of the endTag sequences.
379        // Ignore case only works for english, and should only be relied on when comparing
380        // to English words: StringEqual( p, "version", true ) is fine.
381        static bool StringEqual(        const char* p,
382                                                                const char* endTag,
383                                                                bool ignoreCase,
384                                                                TiXmlEncoding encoding );
385
386        static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
387
388        TiXmlCursor location;
389
390    /// Field containing a generic user pointer
391        void*                   userData;
392
393        // None of these methods are reliable for any language except English.
394        // Good for approximation, not great for accuracy.
395        static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
396        static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
397        inline static int ToLower( int v, TiXmlEncoding encoding )
398        {
399                if ( encoding == TIXML_ENCODING_UTF8 )
400                {
401                        if ( v < 128 ) return tolower( v );
402                        return v;
403                }
404                else
405                {
406                        return tolower( v );
407                }
408        }
409        static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
410
411private:
412        TiXmlBase( const TiXmlBase& );                          // not implemented.
413        void operator=( const TiXmlBase& base );        // not allowed.
414
415        struct Entity
416        {
417                const char*     str;
418                unsigned int    strLength;
419                char                chr;
420        };
421        enum
422        {
423                NUM_ENTITY = 5,
424                MAX_ENTITY_LENGTH = 6
425
426        };
427        static Entity entity[ NUM_ENTITY ];
428        static bool condenseWhiteSpace;
429};
430
431
432/** The parent class for everything in the Document Object Model.
433        (Except for attributes).
434        Nodes have siblings, a parent, and children. A node can be
435        in a document, or stand on its own. The type of a TiXmlNode
436        can be queried, and it can be cast to its more defined type.
437*/
438class TiXmlNode : public TiXmlBase
439{
440        friend class TiXmlDocument;
441        friend class TiXmlElement;
442
443public:
444        #ifdef TIXML_USE_STL
445
446            /** An input stream operator, for every class. Tolerant of newlines and
447                    formatting, but doesn't expect them.
448            */
449            friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
450
451            /** An output stream operator, for every class. Note that this outputs
452                    without any newlines or formatting, as opposed to Print(), which
453                    includes tabs and new lines.
454
455                    The operator<< and operator>> are not completely symmetric. Writing
456                    a node to a stream is very well defined. You'll get a nice stream
457                    of output, without any extra whitespace or newlines.
458
459                    But reading is not as well defined. (As it always is.) If you create
460                    a TiXmlElement (for example) and read that from an input stream,
461                    the text needs to define an element or junk will result. This is
462                    true of all input streams, but it's worth keeping in mind.
463
464                    A TiXmlDocument will read nodes until it reads a root element, and
465                        all the children of that root element.
466            */
467            friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
468
469                /// Appends the XML node or attribute to a std::string.
470                friend std::string& operator<< (std::string& out, const TiXmlNode& base );
471
472        #endif
473
474        /** The types of XML nodes supported by TinyXml. (All the
475                        unsupported types are picked up by UNKNOWN.)
476        */
477        enum NodeType
478        {
479                DOCUMENT,
480                ELEMENT,
481                COMMENT,
482                UNKNOWN,
483                TEXT,
484                DECLARATION,
485                STYLESHEETREFERENCE,
486                TYPECOUNT
487        };
488
489        virtual ~TiXmlNode();
490
491        /** The meaning of 'value' changes for the specific type of
492                TiXmlNode.
493                @verbatim
494                Document:       filename of the xml file
495                Element:        name of the element
496                Comment:        the comment text
497                Unknown:        the tag contents
498                Text:           the text string
499                @endverbatim
500
501                The subclasses will wrap this function.
502        */
503        const char *Value() const { return value.c_str (); }
504
505    #ifdef TIXML_USE_STL
506        /** Return Value() as a std::string. If you only use STL,
507            this is more efficient than calling Value().
508                Only available in STL mode.
509        */
510        const std::string& ValueStr() const { return value; }
511        #endif
512
513        const TIXML_STRING& ValueTStr() const { return value; }
514
515        /** Changes the value of the node. Defined as:
516                @verbatim
517                Document:       filename of the xml file
518                Element:        name of the element
519                Comment:        the comment text
520                Unknown:        the tag contents
521                Text:           the text string
522                @endverbatim
523        */
524        void SetValue(const char * _value) { value = _value;}
525
526    #ifdef TIXML_USE_STL
527        /// STL std::string form.
528        void SetValue( const std::string& _value )      { value = _value; }
529        #endif
530
531        /// Delete all the children of this node. Does not affect 'this'.
532        void Clear();
533
534        /// One step up the DOM.
535        TiXmlNode* Parent()                                                     { return parent; }
536        const TiXmlNode* Parent() const                         { return parent; }
537
538        const TiXmlNode* FirstChild()   const           { return firstChild; }  ///< The first child of this node. Will be null if there are no children.
539        TiXmlNode* FirstChild()                                         { return firstChild; }
540        const TiXmlNode* FirstChild( const char * value ) const;                        ///< The first child of this node with the matching 'value'. Will be null if none found.
541        /// The first child of this node with the matching 'value'. Will be null if none found.
542        TiXmlNode* FirstChild( const char * _value ) {
543                // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
544                // call the method, cast the return back to non-const.
545                return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
546        }
547        const TiXmlNode* LastChild() const      { return lastChild; }           /// The last child of this node. Will be null if there are no children.
548        TiXmlNode* LastChild()  { return lastChild; }
549
550        const TiXmlNode* LastChild( const char * value ) const;                 /// The last child of this node matching 'value'. Will be null if there are no children.
551        TiXmlNode* LastChild( const char * _value ) {
552                return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
553        }
554
555    #ifdef TIXML_USE_STL
556        const TiXmlNode* FirstChild( const std::string& _value ) const  {       return FirstChild (_value.c_str ());    }       ///< STL std::string form.
557        TiXmlNode* FirstChild( const std::string& _value )                              {       return FirstChild (_value.c_str ());    }       ///< STL std::string form.
558        const TiXmlNode* LastChild( const std::string& _value ) const   {       return LastChild (_value.c_str ());     }       ///< STL std::string form.
559        TiXmlNode* LastChild( const std::string& _value )                               {       return LastChild (_value.c_str ());     }       ///< STL std::string form.
560        #endif
561
562        /** An alternate way to walk the children of a node.
563                One way to iterate over nodes is:
564                @verbatim
565                        for( child = parent->FirstChild(); child; child = child->NextSibling() )
566                @endverbatim
567
568                IterateChildren does the same thing with the syntax:
569                @verbatim
570                        child = 0;
571                        while( child = parent->IterateChildren( child ) )
572                @endverbatim
573
574                IterateChildren takes the previous child as input and finds
575                the next one. If the previous child is null, it returns the
576                first. IterateChildren will return null when done.
577        */
578        const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
579        TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
580                return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
581        }
582
583        /// This flavor of IterateChildren searches for children with a particular 'value'
584        const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
585        TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
586                return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
587        }
588
589    #ifdef TIXML_USE_STL
590        const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const  {       return IterateChildren (_value.c_str (), previous);     }       ///< STL std::string form.
591        TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {    return IterateChildren (_value.c_str (), previous);     }       ///< STL std::string form.
592        #endif
593
594        /** Add a new node related to this. Adds a child past the LastChild.
595                Returns a pointer to the new object or NULL if an error occured.
596        */
597        TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
598
599
600        /** Add a new node related to this. Adds a child past the LastChild.
601
602                NOTE: the node to be added is passed by pointer, and will be
603                henceforth owned (and deleted) by tinyXml. This method is efficient
604                and avoids an extra copy, but should be used with care as it
605                uses a different memory model than the other insert functions.
606
607                @sa InsertEndChild
608        */
609        TiXmlNode* LinkEndChild( TiXmlNode* addThis );
610
611        /** Add a new node related to this. Adds a child before the specified child.
612                Returns a pointer to the new object or NULL if an error occured.
613        */
614        TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
615
616        /** Add a new node related to this. Adds a child after the specified child.
617                Returns a pointer to the new object or NULL if an error occured.
618        */
619        TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
620
621        /** Replace a child of this node.
622                Returns a pointer to the new object or NULL if an error occured.
623        */
624        TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
625
626        /// Delete a child of this node.
627        bool RemoveChild( TiXmlNode* removeThis );
628
629        /// Navigate to a sibling node.
630        const TiXmlNode* PreviousSibling() const                        { return prev; }
631        TiXmlNode* PreviousSibling()                                            { return prev; }
632
633        /// Navigate to a sibling node.
634        const TiXmlNode* PreviousSibling( const char * ) const;
635        TiXmlNode* PreviousSibling( const char *_prev ) {
636                return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
637        }
638
639    #ifdef TIXML_USE_STL
640        const TiXmlNode* PreviousSibling( const std::string& _value ) const     {       return PreviousSibling (_value.c_str ());       }       ///< STL std::string form.
641        TiXmlNode* PreviousSibling( const std::string& _value )                         {       return PreviousSibling (_value.c_str ());       }       ///< STL std::string form.
642        const TiXmlNode* NextSibling( const std::string& _value) const          {       return NextSibling (_value.c_str ());   }       ///< STL std::string form.
643        TiXmlNode* NextSibling( const std::string& _value)                                      {       return NextSibling (_value.c_str ());   }       ///< STL std::string form.
644        #endif
645
646        /// Navigate to a sibling node.
647        const TiXmlNode* NextSibling() const                            { return next; }
648        TiXmlNode* NextSibling()                                                        { return next; }
649
650        /// Navigate to a sibling node with the given 'value'.
651        const TiXmlNode* NextSibling( const char * ) const;
652        TiXmlNode* NextSibling( const char* _next ) {
653                return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
654        }
655
656        /** Convenience function to get through elements.
657                Calls NextSibling and ToElement. Will skip all non-Element
658                nodes. Returns 0 if there is not another element.
659        */
660        const TiXmlElement* NextSiblingElement() const;
661        TiXmlElement* NextSiblingElement() {
662                return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
663        }
664
665        /** Convenience function to get through elements.
666                Calls NextSibling and ToElement. Will skip all non-Element
667                nodes. Returns 0 if there is not another element.
668        */
669        const TiXmlElement* NextSiblingElement( const char * ) const;
670        TiXmlElement* NextSiblingElement( const char *_next ) {
671                return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
672        }
673
674    #ifdef TIXML_USE_STL
675        const TiXmlElement* NextSiblingElement( const std::string& _value) const        {       return NextSiblingElement (_value.c_str ());    }       ///< STL std::string form.
676        TiXmlElement* NextSiblingElement( const std::string& _value)                            {       return NextSiblingElement (_value.c_str ());    }       ///< STL std::string form.
677        #endif
678
679        /// Convenience function to get through elements.
680        const TiXmlElement* FirstChildElement() const;
681        TiXmlElement* FirstChildElement() {
682                return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
683        }
684
685        /// Convenience function to get through elements.
686        const TiXmlElement* FirstChildElement( const char * _value ) const;
687        TiXmlElement* FirstChildElement( const char * _value ) {
688                return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
689        }
690
691    #ifdef TIXML_USE_STL
692        const TiXmlElement* FirstChildElement( const std::string& _value ) const        {       return FirstChildElement (_value.c_str ());     }       ///< STL std::string form.
693        TiXmlElement* FirstChildElement( const std::string& _value )                            {       return FirstChildElement (_value.c_str ());     }       ///< STL std::string form.
694        #endif
695
696        /** Query the type (as an enumerated value, above) of this node.
697                The possible types are: DOCUMENT, ELEMENT, COMMENT,
698                                                                UNKNOWN, TEXT, and DECLARATION.
699        */
700        int Type() const        { return type; }
701
702        /** Return a pointer to the Document this node lives in.
703                Returns null if not in a document.
704        */
705        const TiXmlDocument* GetDocument() const;
706        TiXmlDocument* GetDocument() {
707                return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
708        }
709
710        /// Returns true if this node has no children.
711        bool NoChildren() const                                         { return !firstChild; }
712
713        virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
714        virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
715        virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
716        virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
717        virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
718        virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
719        virtual const TiXmlStylesheetReference* ToStylesheetReference() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
720
721        virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
722        virtual TiXmlElement*           ToElement()         { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
723        virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
724        virtual TiXmlUnknown*           ToUnknown()         { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
725        virtual TiXmlText*                  ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
726        virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
727        virtual TiXmlStylesheetReference*       ToStylesheetReference() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
728
729        /** Create an exact duplicate of this node and return it. The memory must be deleted
730                by the caller.
731        */
732        virtual TiXmlNode* Clone() const = 0;
733
734        /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
735                XML tree will be conditionally visited and the host will be called back
736                via the TiXmlVisitor interface.
737
738                This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
739                the XML for the callbacks, so the performance of TinyXML is unchanged by using this
740                interface versus any other.)
741
742                The interface has been based on ideas from:
743
744                - http://www.saxproject.org/
745                - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
746
747                Which are both good references for "visiting".
748
749                An example of using Accept():
750                @verbatim
751                TiXmlPrinter printer;
752                tinyxmlDoc.Accept( &printer );
753                const char* xmlcstr = printer.CStr();
754                @endverbatim
755        */
756        virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
757
758protected:
759        TiXmlNode( NodeType _type );
760
761        // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
762        // and the assignment operator.
763        void CopyTo( TiXmlNode* target ) const;
764
765        #ifdef TIXML_USE_STL
766            // The real work of the input operator.
767        virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
768        #endif
769
770        // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
771        TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
772
773        TiXmlNode*              parent;
774        NodeType                type;
775
776        TiXmlNode*              firstChild;
777        TiXmlNode*              lastChild;
778
779        TIXML_STRING    value;
780
781        TiXmlNode*              prev;
782        TiXmlNode*              next;
783
784private:
785        TiXmlNode( const TiXmlNode& );                          // not implemented.
786        void operator=( const TiXmlNode& base );        // not allowed.
787};
788
789
790/** An attribute is a name-value pair. Elements have an arbitrary
791        number of attributes, each with a unique name.
792
793        @note The attributes are not TiXmlNodes, since they are not
794                  part of the tinyXML document object model. There are other
795                  suggested ways to look at this problem.
796*/
797class TiXmlAttribute : public TiXmlBase
798{
799        friend class TiXmlAttributeSet;
800
801public:
802        /// Construct an empty attribute.
803        TiXmlAttribute() : TiXmlBase()
804        {
805                document = 0;
806                prev = next = 0;
807        }
808
809        #ifdef TIXML_USE_STL
810        /// std::string constructor.
811        TiXmlAttribute( const std::string& _name, const std::string& _value )
812        {
813                name = _name;
814                value = _value;
815                document = 0;
816                prev = next = 0;
817        }
818        #endif
819
820        /// Construct an attribute with a name and value.
821        TiXmlAttribute( const char * _name, const char * _value )
822        {
823                name = _name;
824                value = _value;
825                document = 0;
826                prev = next = 0;
827        }
828
829        const char*             Name()  const           { return name.c_str(); }                ///< Return the name of this attribute.
830        const char*             Value() const           { return value.c_str(); }               ///< Return the value of this attribute.
831        #ifdef TIXML_USE_STL
832        const std::string& ValueStr() const     { return value; }                               ///< Return the value of this attribute.
833        #endif
834        int                             IntValue() const;                                                                       ///< Return the value of this attribute, converted to an integer.
835        double                  DoubleValue() const;                                                            ///< Return the value of this attribute, converted to a double.
836
837        // Get the tinyxml string representation
838        const TIXML_STRING& NameTStr() const { return name; }
839
840        /** QueryIntValue examines the value string. It is an alternative to the
841                IntValue() method with richer error checking.
842                If the value is an integer, it is stored in 'value' and
843                the call returns TIXML_SUCCESS. If it is not
844                an integer, it returns TIXML_WRONG_TYPE.
845
846                A specialized but useful call. Note that for success it returns 0,
847                which is the opposite of almost all other TinyXml calls.
848        */
849        int QueryIntValue( int* _value ) const;
850        /// QueryDoubleValue examines the value string. See QueryIntValue().
851        int QueryDoubleValue( double* _value ) const;
852
853        void SetName( const char* _name )       { name = _name; }                               ///< Set the name of this attribute.
854        void SetValue( const char* _value )     { value = _value; }                             ///< Set the value.
855
856        void SetIntValue( int _value );                                                                         ///< Set the value from an integer.
857        void SetDoubleValue( double _value );                                                           ///< Set the value from a double.
858
859    #ifdef TIXML_USE_STL
860        /// STL std::string form.
861        void SetName( const std::string& _name )        { name = _name; }
862        /// STL std::string form.
863        void SetValue( const std::string& _value )      { value = _value; }
864        #endif
865
866        /// Get the next sibling attribute in the DOM. Returns null at end.
867        const TiXmlAttribute* Next() const;
868        TiXmlAttribute* Next() {
869                return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
870        }
871
872        /// Get the previous sibling attribute in the DOM. Returns null at beginning.
873        const TiXmlAttribute* Previous() const;
874        TiXmlAttribute* Previous() {
875                return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
876        }
877
878        bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
879        bool operator<( const TiXmlAttribute& rhs )      const { return name < rhs.name; }
880        bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
881
882        /*      Attribute parsing starts: first letter of the name
883                                                 returns: the next char after the value end quote
884        */
885        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
886
887        // Prints this Attribute to a FILE stream.
888        virtual void Print( FILE* cfile, int depth ) const {
889                Print( cfile, depth, 0 );
890        }
891        void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
892
893        // [internal use]
894        // Set the document pointer so the attribute can report errors.
895        void SetDocument( TiXmlDocument* doc )  { document = doc; }
896
897private:
898        TiXmlAttribute( const TiXmlAttribute& );                                // not implemented.
899        void operator=( const TiXmlAttribute& base );   // not allowed.
900
901        TiXmlDocument*  document;       // A pointer back to a document, for error reporting.
902        TIXML_STRING name;
903        TIXML_STRING value;
904        TiXmlAttribute* prev;
905        TiXmlAttribute* next;
906};
907
908
909/*      A class used to manage a group of attributes.
910        It is only used internally, both by the ELEMENT and the DECLARATION.
911
912        The set can be changed transparent to the Element and Declaration
913        classes that use it, but NOT transparent to the Attribute
914        which has to implement a next() and previous() method. Which makes
915        it a bit problematic and prevents the use of STL.
916
917        This version is implemented with circular lists because:
918                - I like circular lists
919                - it demonstrates some independence from the (typical) doubly linked list.
920*/
921class TiXmlAttributeSet
922{
923public:
924        TiXmlAttributeSet();
925        ~TiXmlAttributeSet();
926
927        void Add( TiXmlAttribute* attribute );
928        void Remove( TiXmlAttribute* attribute );
929
930        const TiXmlAttribute* First()   const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
931        TiXmlAttribute* First()                                 { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
932        const TiXmlAttribute* Last() const              { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
933        TiXmlAttribute* Last()                                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
934
935        const TiXmlAttribute*   Find( const char* _name ) const;
936        TiXmlAttribute* Find( const char* _name ) {
937                return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
938        }
939        #ifdef TIXML_USE_STL
940        const TiXmlAttribute*   Find( const std::string& _name ) const;
941        TiXmlAttribute* Find( const std::string& _name ) {
942                return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
943        }
944
945        #endif
946
947private:
948        //*ME:  Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
949        //*ME:  this class must be also use a hidden/disabled copy-constructor !!!
950        TiXmlAttributeSet( const TiXmlAttributeSet& );  // not allowed
951        void operator=( const TiXmlAttributeSet& );     // not allowed (as TiXmlAttribute)
952
953        TiXmlAttribute sentinel;
954};
955
956
957/** The element is a container class. It has a value, the element name,
958        and can contain other elements, text, comments, and unknowns.
959        Elements also contain an arbitrary number of attributes.
960*/
961class TiXmlElement : public TiXmlNode
962{
963public:
964        /// Construct an element.
965        TiXmlElement (const char * in_value);
966
967        #ifdef TIXML_USE_STL
968        /// std::string constructor.
969        TiXmlElement( const std::string& _value );
970        #endif
971
972        TiXmlElement( const TiXmlElement& );
973
974        void operator=( const TiXmlElement& base );
975
976        virtual ~TiXmlElement();
977
978        /** Given an attribute name, Attribute() returns the value
979                for the attribute of that name, or null if none exists.
980        */
981        const char* Attribute( const char* name ) const;
982
983        /** Given an attribute name, Attribute() returns the value
984                for the attribute of that name, or null if none exists.
985                If the attribute exists and can be converted to an integer,
986                the integer value will be put in the return 'i', if 'i'
987                is non-null.
988        */
989        const char* Attribute( const char* name, int* i ) const;
990
991        /** Given an attribute name, Attribute() returns the value
992                for the attribute of that name, or null if none exists.
993                If the attribute exists and can be converted to an double,
994                the double value will be put in the return 'd', if 'd'
995                is non-null.
996        */
997        const char* Attribute( const char* name, double* d ) const;
998
999        /** QueryIntAttribute examines the attribute - it is an alternative to the
1000                Attribute() method with richer error checking.
1001                If the attribute is an integer, it is stored in 'value' and
1002                the call returns TIXML_SUCCESS. If it is not
1003                an integer, it returns TIXML_WRONG_TYPE. If the attribute
1004                does not exist, then TIXML_NO_ATTRIBUTE is returned.
1005        */
1006        int QueryIntAttribute( const char* name, int* _value ) const;
1007        /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
1008        int QueryDoubleAttribute( const char* name, double* _value ) const;
1009        /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
1010        int QueryFloatAttribute( const char* name, float* _value ) const {
1011                double d;
1012                int result = QueryDoubleAttribute( name, &d );
1013                if ( result == TIXML_SUCCESS ) {
1014                        *_value = (float)d;
1015                }
1016                return result;
1017        }
1018
1019    #ifdef TIXML_USE_STL
1020        /** Template form of the attribute query which will try to read the
1021                attribute into the specified type. Very easy, very powerful, but
1022                be careful to make sure to call this with the correct type.
1023
1024                NOTE: This method doesn't work correctly for 'string' types.
1025
1026                @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
1027        */
1028        template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
1029        {
1030                const TiXmlAttribute* node = attributeSet.Find( name );
1031                if ( !node )
1032                        return TIXML_NO_ATTRIBUTE;
1033
1034                std::stringstream sstream( node->ValueStr() );
1035                sstream >> *outValue;
1036                if ( !sstream.fail() )
1037                        return TIXML_SUCCESS;
1038                return TIXML_WRONG_TYPE;
1039        }
1040        /*
1041         This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string"
1042         but template specialization is hard to get working cross-compiler. Leaving the bug for now.
1043
1044        // The above will fail for std::string because the space character is used as a seperator.
1045        // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string
1046        template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const
1047        {
1048                const TiXmlAttribute* node = attributeSet.Find( name );
1049                if ( !node )
1050                        return TIXML_NO_ATTRIBUTE;
1051                *outValue = node->ValueStr();
1052                return TIXML_SUCCESS;
1053        }
1054        */
1055        #endif
1056
1057        /** Sets an attribute of name to a given value. The attribute
1058                will be created if it does not exist, or changed if it does.
1059        */
1060        void SetAttribute( const char* name, const char * _value );
1061
1062    #ifdef TIXML_USE_STL
1063        const std::string* Attribute( const std::string& name ) const;
1064        const std::string* Attribute( const std::string& name, int* i ) const;
1065        const std::string* Attribute( const std::string& name, double* d ) const;
1066        int QueryIntAttribute( const std::string& name, int* _value ) const;
1067        int QueryDoubleAttribute( const std::string& name, double* _value ) const;
1068
1069        /// STL std::string form.
1070        void SetAttribute( const std::string& name, const std::string& _value );
1071        ///< STL std::string form.
1072        void SetAttribute( const std::string& name, int _value );
1073        #endif
1074
1075        /** Sets an attribute of name to a given value. The attribute
1076                will be created if it does not exist, or changed if it does.
1077        */
1078        void SetAttribute( const char * name, int value );
1079
1080        /** Sets an attribute of name to a given value. The attribute
1081                will be created if it does not exist, or changed if it does.
1082        */
1083        void SetDoubleAttribute( const char * name, double value );
1084
1085        /** Deletes an attribute with the given name.
1086        */
1087        void RemoveAttribute( const char * name );
1088    #ifdef TIXML_USE_STL
1089        void RemoveAttribute( const std::string& name ) {       RemoveAttribute (name.c_str ());        }       ///< STL std::string form.
1090        #endif
1091
1092        const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }                ///< Access the first attribute in this element.
1093        TiXmlAttribute* FirstAttribute()                                { return attributeSet.First(); }
1094        const TiXmlAttribute* LastAttribute()   const   { return attributeSet.Last(); }         ///< Access the last attribute in this element.
1095        TiXmlAttribute* LastAttribute()                                 { return attributeSet.Last(); }
1096
1097        /** Convenience function for easy access to the text inside an element. Although easy
1098                and concise, GetText() is limited compared to getting the TiXmlText child
1099                and accessing it directly.
1100
1101                If the first child of 'this' is a TiXmlText, the GetText()
1102                returns the character string of the Text node, else null is returned.
1103
1104                This is a convenient method for getting the text of simple contained text:
1105                @verbatim
1106                <foo>This is text</foo>
1107                const char* str = fooElement->GetText();
1108                @endverbatim
1109
1110                'str' will be a pointer to "This is text".
1111
1112                Note that this function can be misleading. If the element foo was created from
1113                this XML:
1114                @verbatim
1115                <foo><b>This is text</b></foo>
1116                @endverbatim
1117
1118                then the value of str would be null. The first child node isn't a text node, it is
1119                another element. From this XML:
1120                @verbatim
1121                <foo>This is <b>text</b></foo>
1122                @endverbatim
1123                GetText() will return "This is ".
1124
1125                WARNING: GetText() accesses a child node - don't become confused with the
1126                                 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
1127                                 safe type casts on the referenced node.
1128        */
1129        const char* GetText() const;
1130
1131        /// Creates a new Element and returns it - the returned element is a copy.
1132        virtual TiXmlNode* Clone() const;
1133        // Print the Element to a FILE stream.
1134        virtual void Print( FILE* cfile, int depth ) const;
1135
1136        /*      Attribtue parsing starts: next char past '<'
1137                                                 returns: next char past '>'
1138        */
1139        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1140
1141        virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1142        virtual TiXmlElement*           ToElement()               { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1143
1144        /** Walk the XML tree visiting this node and all of its children.
1145        */
1146        virtual bool Accept( TiXmlVisitor* visitor ) const;
1147
1148protected:
1149
1150        void CopyTo( TiXmlElement* target ) const;
1151        void ClearThis();       // like clear, but initializes 'this' object as well
1152
1153        // Used to be public [internal use]
1154        #ifdef TIXML_USE_STL
1155        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1156        #endif
1157        /*      [internal use]
1158                Reads the "value" of the element -- another element, or text.
1159                This should terminate with the current end tag.
1160        */
1161        const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1162
1163private:
1164
1165        TiXmlAttributeSet attributeSet;
1166};
1167
1168
1169/**     An XML comment.
1170*/
1171class TiXmlComment : public TiXmlNode
1172{
1173public:
1174        /// Constructs an empty comment.
1175        TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
1176        /// Construct a comment from text.
1177        TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
1178                SetValue( _value );
1179        }
1180        TiXmlComment( const TiXmlComment& );
1181        void operator=( const TiXmlComment& base );
1182
1183        virtual ~TiXmlComment() {}
1184
1185        /// Returns a copy of this Comment.
1186        virtual TiXmlNode* Clone() const;
1187        // Write this Comment to a FILE stream.
1188        virtual void Print( FILE* cfile, int depth ) const;
1189
1190        /*      Attribtue parsing starts: at the ! of the !--
1191                                                 returns: next char past '>'
1192        */
1193        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1194
1195        virtual const TiXmlComment*  ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1196        virtual TiXmlComment*  ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1197
1198        /** Walk the XML tree visiting this node and all of its children.
1199        */
1200        virtual bool Accept( TiXmlVisitor* visitor ) const;
1201
1202protected:
1203        void CopyTo( TiXmlComment* target ) const;
1204
1205        // used to be public
1206        #ifdef TIXML_USE_STL
1207        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1208        #endif
1209//      virtual void StreamOut( TIXML_OSTREAM * out ) const;
1210
1211private:
1212
1213};
1214
1215
1216/** XML text. A text node can have 2 ways to output the next. "normal" output
1217        and CDATA. It will default to the mode it was parsed from the XML file and
1218        you generally want to leave it alone, but you can change the output mode with
1219        SetCDATA() and query it with CDATA().
1220*/
1221class TiXmlText : public TiXmlNode
1222{
1223        friend class TiXmlElement;
1224public:
1225        /** Constructor for text element. By default, it is treated as
1226                normal, encoded text. If you want it be output as a CDATA text
1227                element, set the parameter _cdata to 'true'
1228        */
1229        TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
1230        {
1231                SetValue( initValue );
1232                cdata = false;
1233        }
1234        virtual ~TiXmlText() {}
1235
1236        #ifdef TIXML_USE_STL
1237        /// Constructor.
1238        TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
1239        {
1240                SetValue( initValue );
1241                cdata = false;
1242        }
1243        #endif
1244
1245        TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )       { copy.CopyTo( this ); }
1246        void operator=( const TiXmlText& base )                                                         { base.CopyTo( this ); }
1247
1248        // Write this text object to a FILE stream.
1249        virtual void Print( FILE* cfile, int depth ) const;
1250
1251        /// Queries whether this represents text using a CDATA section.
1252        bool CDATA() const                              { return cdata; }
1253        /// Turns on or off a CDATA representation of text.
1254        void SetCDATA( bool _cdata )    { cdata = _cdata; }
1255
1256        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1257
1258        virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1259        virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1260
1261        /** Walk the XML tree visiting this node and all of its children.
1262        */
1263        virtual bool Accept( TiXmlVisitor* content ) const;
1264
1265protected :
1266        ///  [internal use] Creates a new Element and returns it.
1267        virtual TiXmlNode* Clone() const;
1268        void CopyTo( TiXmlText* target ) const;
1269
1270        bool Blank() const;     // returns true if all white space and new lines
1271        // [internal use]
1272        #ifdef TIXML_USE_STL
1273        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1274        #endif
1275
1276private:
1277        bool cdata;                     // true if this should be input and output as a CDATA style text element
1278};
1279
1280
1281/** In correct XML the declaration is the first entry in the file.
1282        @verbatim
1283                <?xml version="1.0" standalone="yes"?>
1284        @endverbatim
1285
1286        TinyXml will happily read or write files without a declaration,
1287        however. There are 3 possible attributes to the declaration:
1288        version, encoding, and standalone.
1289
1290        Note: In this version of the code, the attributes are
1291        handled as special cases, not generic attributes, simply
1292        because there can only be at most 3 and they are always the same.
1293*/
1294class TiXmlDeclaration : public TiXmlNode
1295{
1296public:
1297        /// Construct an empty declaration.
1298        TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
1299
1300#ifdef TIXML_USE_STL
1301        /// Constructor.
1302        TiXmlDeclaration(       const std::string& _version,
1303                                                const std::string& _encoding,
1304                                                const std::string& _standalone );
1305#endif
1306
1307        /// Construct.
1308        TiXmlDeclaration(       const char* _version,
1309                                                const char* _encoding,
1310                                                const char* _standalone );
1311
1312        TiXmlDeclaration( const TiXmlDeclaration& copy );
1313        void operator=( const TiXmlDeclaration& copy );
1314
1315        virtual ~TiXmlDeclaration()     {}
1316
1317        /// Version. Will return an empty string if none was found.
1318        const char *Version() const                     { return version.c_str (); }
1319        /// Encoding. Will return an empty string if none was found.
1320        const char *Encoding() const            { return encoding.c_str (); }
1321        /// Is this a standalone document?
1322        const char *Standalone() const          { return standalone.c_str (); }
1323
1324        /// Creates a copy of this Declaration and returns it.
1325        virtual TiXmlNode* Clone() const;
1326        // Print this declaration to a FILE stream.
1327        virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
1328        virtual void Print( FILE* cfile, int depth ) const {
1329                Print( cfile, depth, 0 );
1330        }
1331
1332        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1333
1334        virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1335        virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1336
1337        /** Walk the XML tree visiting this node and all of its children.
1338        */
1339        virtual bool Accept( TiXmlVisitor* visitor ) const;
1340
1341protected:
1342        void CopyTo( TiXmlDeclaration* target ) const;
1343        // used to be public
1344        #ifdef TIXML_USE_STL
1345        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1346        #endif
1347
1348private:
1349
1350        TIXML_STRING version;
1351        TIXML_STRING encoding;
1352        TIXML_STRING standalone;
1353};
1354
1355/** A stylesheet reference looks like this:
1356        @verbatim
1357                <?xml-stylesheet type="text/xsl" href="style.xsl"?>
1358        @endverbatim
1359
1360        Note: In this version of the code, the attributes are
1361        handled as special cases, not generic attributes, simply
1362        because there can only be at most 2 and they are always the same.
1363*/
1364class TiXmlStylesheetReference : public TiXmlNode
1365{
1366public:
1367        /// Construct an empty declaration.
1368        TiXmlStylesheetReference()   : TiXmlNode( TiXmlNode::STYLESHEETREFERENCE ) {}
1369
1370#ifdef TIXML_USE_STL
1371        /// Constructor.
1372        TiXmlStylesheetReference(       const std::string& _type,
1373                                                                const std::string& _href );
1374#endif
1375
1376        /// Construct.
1377        TiXmlStylesheetReference(       const char* _type,
1378                                                                const char* _href );
1379
1380        TiXmlStylesheetReference( const TiXmlStylesheetReference& copy );
1381        void operator=( const TiXmlStylesheetReference& copy );
1382
1383        virtual ~TiXmlStylesheetReference()     {}
1384
1385        /// Type. Will return an empty string if none was found.
1386        const char *Type() const { return type.c_str (); }
1387        /// Href. Will return an empty string if none was found.
1388        const char *Href() const                { return href.c_str (); }
1389
1390        /// Creates a copy of this StylesheetReference and returns it.
1391        virtual TiXmlNode* Clone() const;
1392        // Print this declaration to a FILE stream.
1393        virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
1394        virtual void Print( FILE* cfile, int depth ) const {
1395                Print( cfile, depth, 0 );
1396        }
1397
1398        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1399
1400        virtual const TiXmlStylesheetReference* ToStylesheetReference() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1401        virtual TiXmlStylesheetReference*       ToStylesheetReference()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1402
1403        /** Walk the XML tree visiting this node and all of its children.
1404        */
1405        virtual bool Accept( TiXmlVisitor* visitor ) const;
1406
1407protected:
1408        void CopyTo( TiXmlStylesheetReference* target ) const;
1409        // used to be public
1410        #ifdef TIXML_USE_STL
1411        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1412        #endif
1413
1414private:
1415
1416        TIXML_STRING type;
1417        TIXML_STRING href;
1418};
1419
1420/** Any tag that tinyXml doesn't recognize is saved as an
1421        unknown. It is a tag of text, but should not be modified.
1422        It will be written back to the XML, unchanged, when the file
1423        is saved.
1424
1425        DTD tags get thrown into TiXmlUnknowns.
1426*/
1427class TiXmlUnknown : public TiXmlNode
1428{
1429public:
1430        TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )        {}
1431        virtual ~TiXmlUnknown() {}
1432
1433        TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )              { copy.CopyTo( this ); }
1434        void operator=( const TiXmlUnknown& copy )                                                                              { copy.CopyTo( this ); }
1435
1436        /// Creates a copy of this Unknown and returns it.
1437        virtual TiXmlNode* Clone() const;
1438        // Print this Unknown to a FILE stream.
1439        virtual void Print( FILE* cfile, int depth ) const;
1440
1441        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1442
1443        virtual const TiXmlUnknown*     ToUnknown()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1444        virtual TiXmlUnknown*           ToUnknown()         { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1445
1446        /** Walk the XML tree visiting this node and all of its children.
1447        */
1448        virtual bool Accept( TiXmlVisitor* content ) const;
1449
1450protected:
1451        void CopyTo( TiXmlUnknown* target ) const;
1452
1453        #ifdef TIXML_USE_STL
1454        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1455        #endif
1456
1457private:
1458
1459};
1460
1461
1462/** Always the top level node. A document binds together all the
1463        XML pieces. It can be saved, loaded, and printed to the screen.
1464        The 'value' of a document node is the xml file name.
1465*/
1466class TiXmlDocument : public TiXmlNode
1467{
1468public:
1469        /// Create an empty document, that has no name.
1470        TiXmlDocument();
1471        /// Create a document with a name. The name of the document is also the filename of the xml.
1472        TiXmlDocument( const char * documentName );
1473
1474        #ifdef TIXML_USE_STL
1475        /// Constructor.
1476        TiXmlDocument( const std::string& documentName );
1477        #endif
1478
1479        TiXmlDocument( const TiXmlDocument& copy );
1480        void operator=( const TiXmlDocument& copy );
1481
1482        virtual ~TiXmlDocument() {}
1483
1484        /** Load a file using the current document value.
1485                Returns true if successful. Will delete any existing
1486                document data before loading.
1487        */
1488        bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1489        /// Save a file using the current document value. Returns true if successful.
1490        bool SaveFile() const;
1491        /// Load a file using the given filename. Returns true if successful.
1492        bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1493        /// Save a file using the given filename. Returns true if successful.
1494        bool SaveFile( const char * filename ) const;
1495        /** Load a file using the given FILE*. Returns true if successful. Note that this method
1496                doesn't stream - the entire object pointed at by the FILE*
1497                will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
1498                file location. Streaming may be added in the future.
1499        */
1500        bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1501        /// Save a file using the given FILE*. Returns true if successful.
1502        bool SaveFile( FILE* ) const;
1503
1504        #ifdef TIXML_USE_STL
1505        bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )                   ///< STL std::string version.
1506        {
1507//              StringToBuffer f( filename );
1508//              return ( f.buffer && LoadFile( f.buffer, encoding ));
1509                return LoadFile( filename.c_str(), encoding );
1510        }
1511        bool SaveFile( const std::string& filename ) const              ///< STL std::string version.
1512        {
1513//              StringToBuffer f( filename );
1514//              return ( f.buffer && SaveFile( f.buffer ));
1515                return SaveFile( filename.c_str() );
1516        }
1517        #endif
1518
1519        /** Parse the given null terminated block of xml data. Passing in an encoding to this
1520                method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
1521                to use that encoding, regardless of what TinyXml might otherwise try to detect.
1522        */
1523        virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1524
1525        /** Get the root element -- the only top level element -- of the document.
1526                In well formed XML, there should only be one. TinyXml is tolerant of
1527                multiple elements at the document level.
1528        */
1529        const TiXmlElement* RootElement() const         { return FirstChildElement(); }
1530        TiXmlElement* RootElement()                                     { return FirstChildElement(); }
1531
1532        /** If an error occurs, Error will be set to true. Also,
1533                - The ErrorId() will contain the integer identifier of the error (not generally useful)
1534                - The ErrorDesc() method will return the name of the error. (very useful)
1535                - The ErrorRow() and ErrorCol() will return the location of the error (if known)
1536        */
1537        bool Error() const                                              { return error; }
1538
1539        /// Contains a textual (english) description of the error if one occurs.
1540        const char * ErrorDesc() const  { return errorDesc.c_str (); }
1541
1542        /** Generally, you probably want the error string ( ErrorDesc() ). But if you
1543                prefer the ErrorId, this function will fetch it.
1544        */
1545        int ErrorId()   const                           { return errorId; }
1546
1547        /** Returns the location (if known) of the error. The first column is column 1,
1548                and the first row is row 1. A value of 0 means the row and column wasn't applicable
1549                (memory errors, for example, have no row/column) or the parser lost the error. (An
1550                error in the error reporting, in that case.)
1551
1552                @sa SetTabSize, Row, Column
1553        */
1554        int ErrorRow() const    { return errorLocation.row+1; }
1555        int ErrorCol() const    { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
1556
1557        /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
1558                to report the correct values for row and column. It does not change the output
1559                or input in any way.
1560
1561                By calling this method, with a tab size
1562                greater than 0, the row and column of each node and attribute is stored
1563                when the file is loaded. Very useful for tracking the DOM back in to
1564                the source file.
1565
1566                The tab size is required for calculating the location of nodes. If not
1567                set, the default of 4 is used. The tabsize is set per document. Setting
1568                the tabsize to 0 disables row/column tracking.
1569
1570                Note that row and column tracking is not supported when using operator>>.
1571
1572                The tab size needs to be enabled before the parse or load. Correct usage:
1573                @verbatim
1574                TiXmlDocument doc;
1575                doc.SetTabSize( 8 );
1576                doc.Load( "myfile.xml" );
1577                @endverbatim
1578
1579                @sa Row, Column
1580        */
1581        void SetTabSize( int _tabsize )         { tabsize = _tabsize; }
1582
1583        int TabSize() const     { return tabsize; }
1584
1585        /** If you have handled the error, it can be reset with this call. The error
1586                state is automatically cleared if you Parse a new XML block.
1587        */
1588        void ClearError()                                               {       error = false;
1589                                                                                                errorId = 0;
1590                                                                                                errorDesc = "";
1591                                                                                                errorLocation.row = errorLocation.col = 0;
1592                                                                                                //errorLocation.last = 0;
1593                                                                                        }
1594
1595        /** Write the document to standard out using formatted printing ("pretty print"). */
1596        void Print() const                                              { Print( stdout, 0 ); }
1597
1598        /* Write the document to a string using formatted printing ("pretty print"). This
1599                will allocate a character array (new char[]) and return it as a pointer. The
1600                calling code pust call delete[] on the return char* to avoid a memory leak.
1601        */
1602        //char* PrintToMemory() const;
1603
1604        /// Print this Document to a FILE stream.
1605        virtual void Print( FILE* cfile, int depth = 0 ) const;
1606        // [internal use]
1607        void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1608
1609        virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1610        virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1611
1612        /** Walk the XML tree visiting this node and all of its children.
1613        */
1614        virtual bool Accept( TiXmlVisitor* content ) const;
1615
1616protected :
1617        // [internal use]
1618        virtual TiXmlNode* Clone() const;
1619        #ifdef TIXML_USE_STL
1620        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1621        #endif
1622
1623private:
1624        void CopyTo( TiXmlDocument* target ) const;
1625
1626        bool error;
1627        int  errorId;
1628        TIXML_STRING errorDesc;
1629        int tabsize;
1630        TiXmlCursor errorLocation;
1631        bool useMicrosoftBOM;           // the UTF-8 BOM were found when read. Note this, and try to write.
1632};
1633
1634
1635/**
1636        A TiXmlHandle is a class that wraps a node pointer with null checks; this is
1637        an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
1638        DOM structure. It is a separate utility class.
1639
1640        Take an example:
1641        @verbatim
1642        <Document>
1643                <Element attributeA = "valueA">
1644                        <Child attributeB = "value1" />
1645                        <Child attributeB = "value2" />
1646                </Element>
1647        <Document>
1648        @endverbatim
1649
1650        Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
1651        easy to write a *lot* of code that looks like:
1652
1653        @verbatim
1654        TiXmlElement* root = document.FirstChildElement( "Document" );
1655        if ( root )
1656        {
1657                TiXmlElement* element = root->FirstChildElement( "Element" );
1658                if ( element )
1659                {
1660                        TiXmlElement* child = element->FirstChildElement( "Child" );
1661                        if ( child )
1662                        {
1663                                TiXmlElement* child2 = child->NextSiblingElement( "Child" );
1664                                if ( child2 )
1665                                {
1666                                        // Finally do something useful.
1667        @endverbatim
1668
1669        And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
1670        of such code. A TiXmlHandle checks for null     pointers so it is perfectly safe
1671        and correct to use:
1672
1673        @verbatim
1674        TiXmlHandle docHandle( &document );
1675        TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
1676        if ( child2 )
1677        {
1678                // do something useful
1679        @endverbatim
1680
1681        Which is MUCH more concise and useful.
1682
1683        It is also safe to copy handles - internally they are nothing more than node pointers.
1684        @verbatim
1685        TiXmlHandle handleCopy = handle;
1686        @endverbatim
1687
1688        What they should not be used for is iteration:
1689
1690        @verbatim
1691        int i=0;
1692        while ( true )
1693        {
1694                TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
1695                if ( !child )
1696                        break;
1697                // do something
1698                ++i;
1699        }
1700        @endverbatim
1701
1702        It seems reasonable, but it is in fact two embedded while loops. The Child method is
1703        a linear walk to find the element, so this code would iterate much more than it needs
1704        to. Instead, prefer:
1705
1706        @verbatim
1707        TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
1708
1709        for( child; child; child=child->NextSiblingElement() )
1710        {
1711                // do something
1712        }
1713        @endverbatim
1714*/
1715class TiXmlHandle
1716{
1717public:
1718        /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
1719        TiXmlHandle( TiXmlNode* _node )                                 { this->node = _node; }
1720        /// Copy constructor
1721        TiXmlHandle( const TiXmlHandle& ref )                   { this->node = ref.node; }
1722        TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
1723
1724        /// Return a handle to the first child node.
1725        TiXmlHandle FirstChild() const;
1726        /// Return a handle to the first child node with the given name.
1727        TiXmlHandle FirstChild( const char * value ) const;
1728        /// Return a handle to the first child element.
1729        TiXmlHandle FirstChildElement() const;
1730        /// Return a handle to the first child element with the given name.
1731        TiXmlHandle FirstChildElement( const char * value ) const;
1732
1733        /** Return a handle to the "index" child with the given name.
1734                The first child is 0, the second 1, etc.
1735        */
1736        TiXmlHandle Child( const char* value, int index ) const;
1737        /** Return a handle to the "index" child.
1738                The first child is 0, the second 1, etc.
1739        */
1740        TiXmlHandle Child( int index ) const;
1741        /** Return a handle to the "index" child element with the given name.
1742                The first child element is 0, the second 1, etc. Note that only TiXmlElements
1743                are indexed: other types are not counted.
1744        */
1745        TiXmlHandle ChildElement( const char* value, int index ) const;
1746        /** Return a handle to the "index" child element.
1747                The first child element is 0, the second 1, etc. Note that only TiXmlElements
1748                are indexed: other types are not counted.
1749        */
1750        TiXmlHandle ChildElement( int index ) const;
1751
1752        #ifdef TIXML_USE_STL
1753        TiXmlHandle FirstChild( const std::string& _value ) const                               { return FirstChild( _value.c_str() ); }
1754        TiXmlHandle FirstChildElement( const std::string& _value ) const                { return FirstChildElement( _value.c_str() ); }
1755
1756        TiXmlHandle Child( const std::string& _value, int index ) const                 { return Child( _value.c_str(), index ); }
1757        TiXmlHandle ChildElement( const std::string& _value, int index ) const  { return ChildElement( _value.c_str(), index ); }
1758        #endif
1759
1760        /** Return the handle as a TiXmlNode. This may return null.
1761        */
1762        TiXmlNode* ToNode() const                       { return node; }
1763        /** Return the handle as a TiXmlElement. This may return null.
1764        */
1765        TiXmlElement* ToElement() const         { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
1766        /**     Return the handle as a TiXmlText. This may return null.
1767        */
1768        TiXmlText* ToText() const                       { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
1769        /** Return the handle as a TiXmlUnknown. This may return null.
1770        */
1771        TiXmlUnknown* ToUnknown() const         { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
1772
1773        /** @deprecated use ToNode.
1774                Return the handle as a TiXmlNode. This may return null.
1775        */
1776        TiXmlNode* Node() const                 { return ToNode(); }
1777        /** @deprecated use ToElement.
1778                Return the handle as a TiXmlElement. This may return null.
1779        */
1780        TiXmlElement* Element() const   { return ToElement(); }
1781        /**     @deprecated use ToText()
1782                Return the handle as a TiXmlText. This may return null.
1783        */
1784        TiXmlText* Text() const                 { return ToText(); }
1785        /** @deprecated use ToUnknown()
1786                Return the handle as a TiXmlUnknown. This may return null.
1787        */
1788        TiXmlUnknown* Unknown() const   { return ToUnknown(); }
1789
1790private:
1791        TiXmlNode* node;
1792};
1793
1794
1795/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
1796
1797        -# Print to memory (especially in non-STL mode)
1798        -# Control formatting (line endings, etc.)
1799
1800        When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
1801        Before calling Accept() you can call methods to control the printing
1802        of the XML document. After TiXmlNode::Accept() is called, the printed document can
1803        be accessed via the CStr(), Str(), and Size() methods.
1804
1805        TiXmlPrinter uses the Visitor API.
1806        @verbatim
1807        TiXmlPrinter printer;
1808        printer.SetIndent( "\t" );
1809
1810        doc.Accept( &printer );
1811        fprintf( stdout, "%s", printer.CStr() );
1812        @endverbatim
1813*/
1814class TiXmlPrinter : public TiXmlVisitor
1815{
1816public:
1817        TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
1818                                         buffer(), indent( "    " ), lineBreak( "\n" ) {}
1819
1820        virtual bool VisitEnter( const TiXmlDocument& doc );
1821        virtual bool VisitExit( const TiXmlDocument& doc );
1822
1823        virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
1824        virtual bool VisitExit( const TiXmlElement& element );
1825
1826        virtual bool Visit( const TiXmlDeclaration& declaration );
1827        virtual bool Visit( const TiXmlText& text );
1828        virtual bool Visit( const TiXmlComment& comment );
1829        virtual bool Visit( const TiXmlUnknown& unknown );
1830
1831        /** Set the indent characters for printing. By default 4 spaces
1832                but tab (\t) is also useful, or null/empty string for no indentation.
1833        */
1834        void SetIndent( const char* _indent )                   { indent = _indent ? _indent : "" ; }
1835        /// Query the indention string.
1836        const char* Indent()                                                    { return indent.c_str(); }
1837        /** Set the line breaking string. By default set to newline (\n).
1838                Some operating systems prefer other characters, or can be
1839                set to the null/empty string for no indenation.
1840        */
1841        void SetLineBreak( const char* _lineBreak )             { lineBreak = _lineBreak ? _lineBreak : ""; }
1842        /// Query the current line breaking string.
1843        const char* LineBreak()                                                 { return lineBreak.c_str(); }
1844
1845        /** Switch over to "stream printing" which is the most dense formatting without
1846                linebreaks. Common when the XML is needed for network transmission.
1847        */
1848        void SetStreamPrinting()                                                { indent = "";
1849                                                                                                          lineBreak = "";
1850                                                                                                        }
1851        /// Return the result.
1852        const char* CStr()                                                              { return buffer.c_str(); }
1853        /// Return the length of the result string.
1854        size_t Size()                                                                   { return buffer.size(); }
1855
1856        #ifdef TIXML_USE_STL
1857        /// Return the result.
1858        const std::string& Str()                                                { return buffer; }
1859        #endif
1860
1861private:
1862        void DoIndent() {
1863                for( int i=0; i<depth; ++i )
1864                        buffer += indent;
1865        }
1866        void DoLineBreak() {
1867                buffer += lineBreak;
1868        }
1869
1870        int depth;
1871        bool simpleTextPrint;
1872        TIXML_STRING buffer;
1873        TIXML_STRING indent;
1874        TIXML_STRING lineBreak;
1875};
1876
1877
1878#ifdef _MSC_VER
1879#pragma warning( pop )
1880#endif
1881
1882#endif
1883
Note: See TracBrowser for help on using the repository browser.