source: tmcsimulator/branches/WorkingFEPSim/tinyxml/tinyxml.h @ 115

Revision 115, 63.3 KB checked in by jtorres, 9 years ago (diff)

back to workingFEPSim, conflict errors

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