OSDN Git Service

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