/[pcsx2_0.9.7]/trunk/3rdparty/tinyxml/tinyxml.h
ViewVC logotype

Contents of /trunk/3rdparty/tinyxml/tinyxml.h

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.22