Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/tinyxml/tinyxml.h @ 710

Last change on this file since 710 was 471, checked in by nicolape, 17 years ago

Added tinyxml library

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