Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogreode/tinyxml/tinyxml.h @ 21

Last change on this file since 21 was 21, checked in by nicolasc, 16 years ago

added ogreode and Colladaplugin

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