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

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