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