Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/spaceshipcontrol/src/lib/parser/tinyxml/tinyxml.h @ 6726

Last change on this file since 6726 was 5819, checked in by bensch, 19 years ago

orxonox/trunk: merged branches world_entities to trunk again
merged with command
svn merge -r5795:HEAD branches/world_entities/ trunk/
no conflicts (what a wonder)

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