Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy2/src/tinyxml/tinyxml.h @ 2457

Last change on this file since 2457 was 1505, checked in by rgrieder, 17 years ago

f* svn: It doesn't even inform you if you attempt to set a non existing property. It is svn:eol-style and not eol-style when using the command by the way…

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