root/vtcross/branches/trnewman/src/tinyxml.h @ 35

Revision 35, 63.1 KB (checked in by trnewman, 16 years ago)

adding c++

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