Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre/Tools/XMLConverter/include/tinyxml.h @ 20

Last change on this file since 20 was 6, checked in by anonymous, 17 years ago

=…

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