source: trunk/src/global/tinyxml.hpp @ 409

Revision 409, 64.4 KB checked in by Eoin, 12 years ago (diff)

Added support for individual xml saves pre torrent but havn't set when to be saved yet.

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