Update to version 2.6.2.
Change-Id: Ia9255d7c343e0a5c9bd22b951b189e347a119e0e
diff --git a/tinyxml.h b/tinyxml.h
index 18cf94f..a3589e5 100644
--- a/tinyxml.h
+++ b/tinyxml.h
@@ -1,6 +1,6 @@
/*
www.sourceforge.net/projects/tinyxml
-Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+Original code by Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
@@ -43,42 +43,40 @@
#define DEBUG
#endif
-#if defined( DEBUG ) && defined( _MSC_VER )
-#include <windows.h>
-#define TIXML_LOG OutputDebugString
-#else
-#define TIXML_LOG printf
-#endif
-
#ifdef TIXML_USE_STL
#include <string>
#include <iostream>
- #define TIXML_STRING std::string
- #define TIXML_ISTREAM std::istream
- #define TIXML_OSTREAM std::ostream
+ #include <sstream>
+ #define TIXML_STRING std::string
#else
#include "tinystr.h"
- #define TIXML_STRING TiXmlString
- #define TIXML_OSTREAM TiXmlOutStream
+ #define TIXML_STRING TiXmlString
#endif
// Deprecated library function hell. Compilers want to use the
// new safe versions. This probably doesn't fully address the problem,
// but it gets closer. There are too many compilers for me to fully
// test. If you get compilation troubles, undefine TIXML_SAFE
+#define TIXML_SAFE
-#define TIXML_SAFE // TinyXml isn't fully buffer overrun protected, safe code. This is work in progress.
#ifdef TIXML_SAFE
- #if defined(_MSC_VER) && (_MSC_VER >= 1200 )
+ #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+ // Microsoft visual studio, version 2005 and higher.
+ #define TIXML_SNPRINTF _snprintf_s
+ #define TIXML_SSCANF sscanf_s
+ #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
// Microsoft visual studio, version 6 and higher.
//#pragma message( "Using _sn* functions." )
#define TIXML_SNPRINTF _snprintf
- #define TIXML_SNSCANF _snscanf
+ #define TIXML_SSCANF sscanf
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
// GCC version 3 and higher.s
//#warning( "Using sn* functions." )
#define TIXML_SNPRINTF snprintf
- #define TIXML_SNSCANF snscanf
+ #define TIXML_SSCANF sscanf
+ #else
+ #define TIXML_SNPRINTF snprintf
+ #define TIXML_SSCANF sscanf
#endif
#endif
@@ -92,8 +90,8 @@
class TiXmlParsingData;
const int TIXML_MAJOR_VERSION = 2;
-const int TIXML_MINOR_VERSION = 4;
-const int TIXML_PATCH_VERSION = 0;
+const int TIXML_MINOR_VERSION = 6;
+const int TIXML_PATCH_VERSION = 2;
/* Internal structure for tracking location of items
in the XML file.
@@ -108,6 +106,50 @@
};
+/**
+ Implements the interface to the "Visitor pattern" (see the Accept() method.)
+ If you call the Accept() method, it requires being passed a TiXmlVisitor
+ class to handle callbacks. For nodes that contain other nodes (Document, Element)
+ you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
+ are simply called with Visit().
+
+ If you return 'true' from a Visit method, recursive parsing will continue. If you return
+ false, <b>no children of this node or its sibilings</b> will be Visited.
+
+ All flavors of Visit methods have a default implementation that returns 'true' (continue
+ visiting). You need to only override methods that are interesting to you.
+
+ Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
+
+ You should never change the document from a callback.
+
+ @sa TiXmlNode::Accept()
+*/
+class TiXmlVisitor
+{
+public:
+ virtual ~TiXmlVisitor() {}
+
+ /// Visit a document.
+ virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; }
+ /// Visit a document.
+ virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; }
+
+ /// Visit an element.
+ virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; }
+ /// Visit an element.
+ virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; }
+
+ /// Visit a declaration
+ virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; }
+ /// Visit a text node
+ virtual bool Visit( const TiXmlText& /*text*/ ) { return true; }
+ /// Visit a comment node
+ virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; }
+ /// Visit an unknown node
+ virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; }
+};
+
// Only used by Attribute::Query functions
enum
{
@@ -156,11 +198,15 @@
friend class TiXmlDocument;
public:
- TiXmlBase() : userData(0) {}
- virtual ~TiXmlBase() {}
+ TiXmlBase() : userData(0) {}
+ virtual ~TiXmlBase() {}
- /** All TinyXml classes can print themselves to a filestream.
- This is a formatted print, and will insert tabs and newlines.
+ /** All TinyXml classes can print themselves to a filestream
+ or the string class (TiXmlString in non-STL mode, std::string
+ in STL mode.) Either or both cfile and str can be null.
+
+ This is a formatted print, and will insert
+ tabs and newlines.
(For an unformatted stream, use the << operator.)
*/
@@ -170,7 +216,7 @@
not. In order to make everyone happy, these global, static functions
are provided to set whether or not TinyXml will condense all white space
into a single space or not. The default is to condense. Note changing this
- values is not thread safe.
+ value is not thread safe.
*/
static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
@@ -198,8 +244,9 @@
int Row() const { return location.row + 1; }
int Column() const { return location.col + 1; } ///< See Row()
- void SetUserData( void* user ) { userData = user; }
- void* GetUserData() { return userData; }
+ void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data.
+ void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data.
+ const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data.
// Table that returs, for a given lead byte, the total number of bytes
// in the UTF-8 sequence.
@@ -209,12 +256,16 @@
TiXmlParsingData* data,
TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+ /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
+ or they will be transformed into entities!
+ */
+ static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
+
enum
{
TIXML_NO_ERROR = 0,
TIXML_ERROR,
TIXML_ERROR_OPENING_FILE,
- TIXML_ERROR_OUT_OF_MEMORY,
TIXML_ERROR_PARSING_ELEMENT,
TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
TIXML_ERROR_READING_ELEMENT_VALUE,
@@ -227,33 +278,29 @@
TIXML_ERROR_DOCUMENT_EMPTY,
TIXML_ERROR_EMBEDDED_NULL,
TIXML_ERROR_PARSING_CDATA,
+ TIXML_ERROR_DOCUMENT_TOP_ONLY,
TIXML_ERROR_STRING_COUNT
};
protected:
- // See STL_STRING_BUG
- // Utility class to overcome a bug.
- class StringToBuffer
- {
- public:
- StringToBuffer( const TIXML_STRING& str );
- ~StringToBuffer();
- char* buffer;
- };
+ static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
- static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
- inline static bool IsWhiteSpace( char c )
+ inline static bool IsWhiteSpace( char c )
{
return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
}
-
- virtual void StreamOut (TIXML_OSTREAM *) const = 0;
+ inline static bool IsWhiteSpace( int c )
+ {
+ if ( c < 256 )
+ return IsWhiteSpace( (char) c );
+ return false; // Again, only truly correct for English/Latin...but usually works.
+ }
#ifdef TIXML_USE_STL
- static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
- static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
+ static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
+ static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
#endif
/* Reads an XML name into the string provided. Returns
@@ -282,7 +329,7 @@
assert( p );
if ( encoding == TIXML_ENCODING_UTF8 )
{
- *length = utf8ByteTable[ *((unsigned char*)p) ];
+ *length = utf8ByteTable[ *((const unsigned char*)p) ];
assert( *length >= 0 && *length < 5 );
}
else
@@ -313,12 +360,6 @@
}
}
- // Puts a string to a stream, expanding entities as it goes.
- // Note this should not contian the '<', '>', etc, or they will be transformed into entities!
- static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
-
- static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
-
// Return true if the next characters in the stream are any of the endTag sequences.
// Ignore case only works for english, and should only be relied on when comparing
// to English words: StringEqual( p, "version", true ) is fine.
@@ -413,9 +454,6 @@
/// Appends the XML node or attribute to a std::string.
friend std::string& operator<< (std::string& out, const TiXmlNode& base );
- #else
- // Used internally, not part of the public API.
- friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
#endif
/** The types of XML nodes supported by TinyXml. (All the
@@ -423,13 +461,13 @@
*/
enum NodeType
{
- DOCUMENT,
- ELEMENT,
- COMMENT,
- UNKNOWN,
- TEXT,
- DECLARATION,
- TYPECOUNT
+ TINYXML_DOCUMENT,
+ TINYXML_ELEMENT,
+ TINYXML_COMMENT,
+ TINYXML_UNKNOWN,
+ TINYXML_TEXT,
+ TINYXML_DECLARATION,
+ TINYXML_TYPECOUNT
};
virtual ~TiXmlNode();
@@ -456,6 +494,8 @@
const std::string& ValueStr() const { return value; }
#endif
+ const TIXML_STRING& ValueTStr() const { return value; }
+
/** Changes the value of the node. Defined as:
@verbatim
Document: filename of the xml file
@@ -469,11 +509,7 @@
#ifdef TIXML_USE_STL
/// STL std::string form.
- void SetValue( const std::string& _value )
- {
- StringToBuffer buf( _value );
- SetValue( buf.buffer ? buf.buffer : "" );
- }
+ void SetValue( const std::string& _value ) { value = _value; }
#endif
/// Delete all the children of this node. Does not affect 'this'.
@@ -483,15 +519,22 @@
TiXmlNode* Parent() { return parent; }
const TiXmlNode* Parent() const { return parent; }
- const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children.
- TiXmlNode* FirstChild() { return firstChild; }
+ const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children.
+ TiXmlNode* FirstChild() { return firstChild; }
const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found.
- TiXmlNode* FirstChild( const char * value ); ///< The first child of this node with the matching 'value'. Will be null if none found.
-
+ /// The first child of this node with the matching 'value'. Will be null if none found.
+ TiXmlNode* FirstChild( const char * _value ) {
+ // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
+ // call the method, cast the return back to non-const.
+ return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
+ }
const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children.
TiXmlNode* LastChild() { return lastChild; }
+
const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children.
- TiXmlNode* LastChild( const char * value );
+ TiXmlNode* LastChild( const char * _value ) {
+ return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
+ }
#ifdef TIXML_USE_STL
const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form.
@@ -517,15 +560,19 @@
first. IterateChildren will return null when done.
*/
const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
- TiXmlNode* IterateChildren( TiXmlNode* previous );
+ TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
+ return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
+ }
/// This flavor of IterateChildren searches for children with a particular 'value'
const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
- TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous );
+ TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
+ return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
+ }
#ifdef TIXML_USE_STL
const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
- TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
+ TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
#endif
/** Add a new node related to this. Adds a child past the LastChild.
@@ -569,7 +616,9 @@
/// Navigate to a sibling node.
const TiXmlNode* PreviousSibling( const char * ) const;
- TiXmlNode* PreviousSibling( const char * );
+ TiXmlNode* PreviousSibling( const char *_prev ) {
+ return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
+ }
#ifdef TIXML_USE_STL
const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
@@ -584,21 +633,27 @@
/// Navigate to a sibling node with the given 'value'.
const TiXmlNode* NextSibling( const char * ) const;
- TiXmlNode* NextSibling( const char * );
+ TiXmlNode* NextSibling( const char* _next ) {
+ return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
+ }
/** Convenience function to get through elements.
Calls NextSibling and ToElement. Will skip all non-Element
nodes. Returns 0 if there is not another element.
*/
const TiXmlElement* NextSiblingElement() const;
- TiXmlElement* NextSiblingElement();
+ TiXmlElement* NextSiblingElement() {
+ return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
+ }
/** Convenience function to get through elements.
Calls NextSibling and ToElement. Will skip all non-Element
nodes. Returns 0 if there is not another element.
*/
const TiXmlElement* NextSiblingElement( const char * ) const;
- TiXmlElement* NextSiblingElement( const char * );
+ TiXmlElement* NextSiblingElement( const char *_next ) {
+ return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
+ }
#ifdef TIXML_USE_STL
const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
@@ -607,11 +662,15 @@
/// Convenience function to get through elements.
const TiXmlElement* FirstChildElement() const;
- TiXmlElement* FirstChildElement();
+ TiXmlElement* FirstChildElement() {
+ return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
+ }
/// Convenience function to get through elements.
- const TiXmlElement* FirstChildElement( const char * value ) const;
- TiXmlElement* FirstChildElement( const char * value );
+ const TiXmlElement* FirstChildElement( const char * _value ) const;
+ TiXmlElement* FirstChildElement( const char * _value ) {
+ return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
+ }
#ifdef TIXML_USE_STL
const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
@@ -619,39 +678,65 @@
#endif
/** Query the type (as an enumerated value, above) of this node.
- The possible types are: DOCUMENT, ELEMENT, COMMENT,
- UNKNOWN, TEXT, and DECLARATION.
+ The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT,
+ TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION.
*/
- virtual int Type() const { return type; }
+ int Type() const { return type; }
/** Return a pointer to the Document this node lives in.
Returns null if not in a document.
*/
const TiXmlDocument* GetDocument() const;
- TiXmlDocument* GetDocument();
+ TiXmlDocument* GetDocument() {
+ return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
+ }
/// Returns true if this node has no children.
bool NoChildren() const { return !firstChild; }
- const TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (const TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- const TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (const TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- const TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (const TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- const TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (const TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- const TiXmlText* ToText() const { return ( this && type == TEXT ) ? (const TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- const TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (const TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
- TiXmlDocument* ToDocument() { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlElement* ToElement() { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlComment* ToComment() { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlUnknown* ToUnknown() { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlText* ToText() { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
- TiXmlDeclaration* ToDeclaration() { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+ virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
/** Create an exact duplicate of this node and return it. The memory must be deleted
by the caller.
*/
virtual TiXmlNode* Clone() const = 0;
+ /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
+ XML tree will be conditionally visited and the host will be called back
+ via the TiXmlVisitor interface.
+
+ This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
+ the XML for the callbacks, so the performance of TinyXML is unchanged by using this
+ interface versus any other.)
+
+ The interface has been based on ideas from:
+
+ - http://www.saxproject.org/
+ - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
+
+ Which are both good references for "visiting".
+
+ An example of using Accept():
+ @verbatim
+ TiXmlPrinter printer;
+ tinyxmlDoc.Accept( &printer );
+ const char* xmlcstr = printer.CStr();
+ @endverbatim
+ */
+ virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
+
protected:
TiXmlNode( NodeType _type );
@@ -661,7 +746,7 @@
#ifdef TIXML_USE_STL
// The real work of the input operator.
- virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
+ virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
#endif
// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
@@ -723,11 +808,17 @@
prev = next = 0;
}
- const char* Name() const { return name.c_str (); } ///< Return the name of this attribute.
- const char* Value() const { return value.c_str (); } ///< Return the value of this attribute.
+ const char* Name() const { return name.c_str(); } ///< Return the name of this attribute.
+ const char* Value() const { return value.c_str(); } ///< Return the value of this attribute.
+ #ifdef TIXML_USE_STL
+ const std::string& ValueStr() const { return value; } ///< Return the value of this attribute.
+ #endif
int IntValue() const; ///< Return the value of this attribute, converted to an integer.
double DoubleValue() const; ///< Return the value of this attribute, converted to a double.
+ // Get the tinyxml string representation
+ const TIXML_STRING& NameTStr() const { return name; }
+
/** QueryIntValue examines the value string. It is an alternative to the
IntValue() method with richer error checking.
If the value is an integer, it is stored in 'value' and
@@ -749,25 +840,22 @@
#ifdef TIXML_USE_STL
/// STL std::string form.
- void SetName( const std::string& _name )
- {
- StringToBuffer buf( _name );
- SetName ( buf.buffer ? buf.buffer : "error" );
- }
+ void SetName( const std::string& _name ) { name = _name; }
/// STL std::string form.
- void SetValue( const std::string& _value )
- {
- StringToBuffer buf( _value );
- SetValue( buf.buffer ? buf.buffer : "error" );
- }
+ void SetValue( const std::string& _value ) { value = _value; }
#endif
/// Get the next sibling attribute in the DOM. Returns null at end.
const TiXmlAttribute* Next() const;
- TiXmlAttribute* Next();
+ TiXmlAttribute* Next() {
+ return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
+ }
+
/// Get the previous sibling attribute in the DOM. Returns null at beginning.
const TiXmlAttribute* Previous() const;
- TiXmlAttribute* Previous();
+ TiXmlAttribute* Previous() {
+ return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
+ }
bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
@@ -779,9 +867,11 @@
virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
// Prints this Attribute to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
+ virtual void Print( FILE* cfile, int depth ) const {
+ Print( cfile, depth, 0 );
+ }
+ void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
- virtual void StreamOut( TIXML_OSTREAM * out ) const;
// [internal use]
// Set the document pointer so the attribute can report errors.
void SetDocument( TiXmlDocument* doc ) { document = doc; }
@@ -824,8 +914,14 @@
const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
- const TiXmlAttribute* Find( const char * name ) const;
- TiXmlAttribute* Find( const char * name );
+ TiXmlAttribute* Find( const char* _name ) const;
+ TiXmlAttribute* FindOrCreate( const char* _name );
+
+# ifdef TIXML_USE_STL
+ TiXmlAttribute* Find( const std::string& _name ) const;
+ TiXmlAttribute* FindOrCreate( const std::string& _name );
+# endif
+
private:
//*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
@@ -854,7 +950,7 @@
TiXmlElement( const TiXmlElement& );
- void operator=( const TiXmlElement& base );
+ TiXmlElement& operator=( const TiXmlElement& base );
virtual ~TiXmlElement();
@@ -887,6 +983,13 @@
does not exist, then TIXML_NO_ATTRIBUTE is returned.
*/
int QueryIntAttribute( const char* name, int* _value ) const;
+ /// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().
+ int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;
+ /** QueryBoolAttribute examines the attribute - see QueryIntAttribute().
+ Note that '1', 'true', or 'yes' are considered true, while '0', 'false'
+ and 'no' are considered false.
+ */
+ int QueryBoolAttribute( const char* name, bool* _value ) const;
/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
int QueryDoubleAttribute( const char* name, double* _value ) const;
/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
@@ -899,33 +1002,66 @@
return result;
}
+ #ifdef TIXML_USE_STL
+ /// QueryStringAttribute examines the attribute - see QueryIntAttribute().
+ int QueryStringAttribute( const char* name, std::string* _value ) const {
+ const char* cstr = Attribute( name );
+ if ( cstr ) {
+ *_value = std::string( cstr );
+ return TIXML_SUCCESS;
+ }
+ return TIXML_NO_ATTRIBUTE;
+ }
+
+ /** Template form of the attribute query which will try to read the
+ attribute into the specified type. Very easy, very powerful, but
+ be careful to make sure to call this with the correct type.
+
+ NOTE: This method doesn't work correctly for 'string' types that contain spaces.
+
+ @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
+ */
+ template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
+ {
+ const TiXmlAttribute* node = attributeSet.Find( name );
+ if ( !node )
+ return TIXML_NO_ATTRIBUTE;
+
+ std::stringstream sstream( node->ValueStr() );
+ sstream >> *outValue;
+ if ( !sstream.fail() )
+ return TIXML_SUCCESS;
+ return TIXML_WRONG_TYPE;
+ }
+
+ int QueryValueAttribute( const std::string& name, std::string* outValue ) const
+ {
+ const TiXmlAttribute* node = attributeSet.Find( name );
+ if ( !node )
+ return TIXML_NO_ATTRIBUTE;
+ *outValue = node->ValueStr();
+ return TIXML_SUCCESS;
+ }
+ #endif
+
/** Sets an attribute of name to a given value. The attribute
will be created if it does not exist, or changed if it does.
*/
void SetAttribute( const char* name, const char * _value );
#ifdef TIXML_USE_STL
- const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); }
- const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); }
- const char* Attribute( const std::string& name, double* d ) const { return Attribute( name.c_str(), d ); }
- int QueryIntAttribute( const std::string& name, int* _value ) const { return QueryIntAttribute( name.c_str(), _value ); }
- int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); }
+ const std::string* Attribute( const std::string& name ) const;
+ const std::string* Attribute( const std::string& name, int* i ) const;
+ const std::string* Attribute( const std::string& name, double* d ) const;
+ int QueryIntAttribute( const std::string& name, int* _value ) const;
+ int QueryDoubleAttribute( const std::string& name, double* _value ) const;
/// STL std::string form.
- void SetAttribute( const std::string& name, const std::string& _value )
- {
- StringToBuffer n( name );
- StringToBuffer v( _value );
- if ( n.buffer && v.buffer )
- SetAttribute (n.buffer, v.buffer );
- }
+ void SetAttribute( const std::string& name, const std::string& _value );
///< STL std::string form.
- void SetAttribute( const std::string& name, int _value )
- {
- StringToBuffer n( name );
- if ( n.buffer )
- SetAttribute (n.buffer, _value);
- }
+ void SetAttribute( const std::string& name, int _value );
+ ///< STL std::string form.
+ void SetDoubleAttribute( const std::string& name, double value );
#endif
/** Sets an attribute of name to a given value. The attribute
@@ -955,7 +1091,7 @@
and accessing it directly.
If the first child of 'this' is a TiXmlText, the GetText()
- returs the character string of the Text node, else null is returned.
+ returns the character string of the Text node, else null is returned.
This is a convenient method for getting the text of simple contained text:
@verbatim
@@ -994,6 +1130,13 @@
*/
virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* visitor ) const;
+
protected:
void CopyTo( TiXmlElement* target ) const;
@@ -1001,10 +1144,8 @@
// Used to be public [internal use]
#ifdef TIXML_USE_STL
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
#endif
- virtual void StreamOut( TIXML_OSTREAM * out ) const;
-
/* [internal use]
Reads the "value" of the element -- another element, or text.
This should terminate with the current end tag.
@@ -1012,7 +1153,6 @@
const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
private:
-
TiXmlAttributeSet attributeSet;
};
@@ -1023,15 +1163,19 @@
{
public:
/// Constructs an empty comment.
- TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
+ TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
+ /// Construct a comment from text.
+ TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
+ SetValue( _value );
+ }
TiXmlComment( const TiXmlComment& );
- void operator=( const TiXmlComment& base );
+ TiXmlComment& operator=( const TiXmlComment& base );
virtual ~TiXmlComment() {}
/// Returns a copy of this Comment.
virtual TiXmlNode* Clone() const;
- /// Write this Comment to a FILE stream.
+ // Write this Comment to a FILE stream.
virtual void Print( FILE* cfile, int depth ) const;
/* Attribtue parsing starts: at the ! of the !--
@@ -1039,14 +1183,21 @@
*/
virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* visitor ) const;
+
protected:
void CopyTo( TiXmlComment* target ) const;
// used to be public
#ifdef TIXML_USE_STL
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
#endif
- virtual void StreamOut( TIXML_OSTREAM * out ) const;
+// virtual void StreamOut( TIXML_OSTREAM * out ) const;
private:
@@ -1066,7 +1217,7 @@
normal, encoded text. If you want it be output as a CDATA text
element, set the parameter _cdata to 'true'
*/
- TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
+ TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
{
SetValue( initValue );
cdata = false;
@@ -1075,36 +1226,42 @@
#ifdef TIXML_USE_STL
/// Constructor.
- TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
+ TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
{
SetValue( initValue );
cdata = false;
}
#endif
- TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); }
- void operator=( const TiXmlText& base ) { base.CopyTo( this ); }
+ TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); }
+ TiXmlText& operator=( const TiXmlText& base ) { base.CopyTo( this ); return *this; }
- /// Write this text object to a FILE stream.
+ // Write this text object to a FILE stream.
virtual void Print( FILE* cfile, int depth ) const;
/// Queries whether this represents text using a CDATA section.
- bool CDATA() { return cdata; }
+ bool CDATA() const { return cdata; }
/// Turns on or off a CDATA representation of text.
void SetCDATA( bool _cdata ) { cdata = _cdata; }
virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* content ) const;
+
protected :
/// [internal use] Creates a new Element and returns it.
virtual TiXmlNode* Clone() const;
void CopyTo( TiXmlText* target ) const;
- virtual void StreamOut ( TIXML_OSTREAM * out ) const;
bool Blank() const; // returns true if all white space and new lines
// [internal use]
#ifdef TIXML_USE_STL
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
#endif
private:
@@ -1129,7 +1286,7 @@
{
public:
/// Construct an empty declaration.
- TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {}
+ TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
#ifdef TIXML_USE_STL
/// Constructor.
@@ -1144,7 +1301,7 @@
const char* _standalone );
TiXmlDeclaration( const TiXmlDeclaration& copy );
- void operator=( const TiXmlDeclaration& copy );
+ TiXmlDeclaration& operator=( const TiXmlDeclaration& copy );
virtual ~TiXmlDeclaration() {}
@@ -1157,18 +1314,27 @@
/// Creates a copy of this Declaration and returns it.
virtual TiXmlNode* Clone() const;
- /// Print this declaration to a FILE stream.
- virtual void Print( FILE* cfile, int depth ) const;
+ // Print this declaration to a FILE stream.
+ virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+ virtual void Print( FILE* cfile, int depth ) const {
+ Print( cfile, depth, 0 );
+ }
virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* visitor ) const;
+
protected:
void CopyTo( TiXmlDeclaration* target ) const;
// used to be public
#ifdef TIXML_USE_STL
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
#endif
- virtual void StreamOut ( TIXML_OSTREAM * out) const;
private:
@@ -1188,26 +1354,32 @@
class TiXmlUnknown : public TiXmlNode
{
public:
- TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
+ TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {}
virtual ~TiXmlUnknown() {}
- TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); }
- void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); }
+ TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); }
+ TiXmlUnknown& operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); return *this; }
/// Creates a copy of this Unknown and returns it.
virtual TiXmlNode* Clone() const;
- /// Print this Unknown to a FILE stream.
+ // Print this Unknown to a FILE stream.
virtual void Print( FILE* cfile, int depth ) const;
virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+ virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* content ) const;
+
protected:
void CopyTo( TiXmlUnknown* target ) const;
#ifdef TIXML_USE_STL
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
#endif
- virtual void StreamOut ( TIXML_OSTREAM * out ) const;
private:
@@ -1232,7 +1404,7 @@
#endif
TiXmlDocument( const TiXmlDocument& copy );
- void operator=( const TiXmlDocument& copy );
+ TiXmlDocument& operator=( const TiXmlDocument& copy );
virtual ~TiXmlDocument() {}
@@ -1247,17 +1419,23 @@
bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
/// Save a file using the given filename. Returns true if successful.
bool SaveFile( const char * filename ) const;
+ /** Load a file using the given FILE*. Returns true if successful. Note that this method
+ doesn't stream - the entire object pointed at by the FILE*
+ will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
+ file location. Streaming may be added in the future.
+ */
+ bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+ /// Save a file using the given FILE*. Returns true if successful.
+ bool SaveFile( FILE* ) const;
#ifdef TIXML_USE_STL
bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version.
{
- StringToBuffer f( filename );
- return ( f.buffer && LoadFile( f.buffer, encoding ));
+ return LoadFile( filename.c_str(), encoding );
}
bool SaveFile( const std::string& filename ) const ///< STL std::string version.
{
- StringToBuffer f( filename );
- return ( f.buffer && SaveFile( f.buffer ));
+ return SaveFile( filename.c_str() );
}
#endif
@@ -1296,8 +1474,8 @@
@sa SetTabSize, Row, Column
*/
- int ErrorRow() { return errorLocation.row+1; }
- int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
+ int ErrorRow() const { return errorLocation.row+1; }
+ int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
to report the correct values for row and column. It does not change the output
@@ -1337,20 +1515,32 @@
//errorLocation.last = 0;
}
- /** Dump the document to standard out. */
+ /** Write the document to standard out using formatted printing ("pretty print"). */
void Print() const { Print( stdout, 0 ); }
+ /* Write the document to a string using formatted printing ("pretty print"). This
+ will allocate a character array (new char[]) and return it as a pointer. The
+ calling code pust call delete[] on the return char* to avoid a memory leak.
+ */
+ //char* PrintToMemory() const;
+
/// Print this Document to a FILE stream.
virtual void Print( FILE* cfile, int depth = 0 ) const;
// [internal use]
void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+ virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+ virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+ /** Walk the XML tree visiting this node and all of its children.
+ */
+ virtual bool Accept( TiXmlVisitor* content ) const;
+
protected :
- virtual void StreamOut ( TIXML_OSTREAM * out) const;
// [internal use]
virtual TiXmlNode* Clone() const;
#ifdef TIXML_USE_STL
- virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+ virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
#endif
private:
@@ -1405,7 +1595,7 @@
@verbatim
TiXmlHandle docHandle( &document );
- TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element();
+ TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
if ( child2 )
{
// do something useful
@@ -1424,7 +1614,7 @@
int i=0;
while ( true )
{
- TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element();
+ TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
if ( !child )
break;
// do something
@@ -1437,7 +1627,7 @@
to. Instead, prefer:
@verbatim
- TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element();
+ TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
for( child; child; child=child->NextSiblingElement() )
{
@@ -1452,7 +1642,7 @@
TiXmlHandle( TiXmlNode* _node ) { this->node = _node; }
/// Copy constructor
TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; }
- TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
+ TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; }
/// Return a handle to the first child node.
TiXmlHandle FirstChild() const;
@@ -1490,22 +1680,126 @@
TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); }
#endif
- /// Return the handle as a TiXmlNode. This may return null.
- TiXmlNode* Node() const { return node; }
- /// Return the handle as a TiXmlElement. This may return null.
- TiXmlElement* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
- /// Return the handle as a TiXmlText. This may return null.
- TiXmlText* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
- /// Return the handle as a TiXmlUnknown. This may return null;
- TiXmlUnknown* Unknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+ /** Return the handle as a TiXmlNode. This may return null.
+ */
+ TiXmlNode* ToNode() const { return node; }
+ /** Return the handle as a TiXmlElement. This may return null.
+ */
+ TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+ /** Return the handle as a TiXmlText. This may return null.
+ */
+ TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+ /** Return the handle as a TiXmlUnknown. This may return null.
+ */
+ TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+ /** @deprecated use ToNode.
+ Return the handle as a TiXmlNode. This may return null.
+ */
+ TiXmlNode* Node() const { return ToNode(); }
+ /** @deprecated use ToElement.
+ Return the handle as a TiXmlElement. This may return null.
+ */
+ TiXmlElement* Element() const { return ToElement(); }
+ /** @deprecated use ToText()
+ Return the handle as a TiXmlText. This may return null.
+ */
+ TiXmlText* Text() const { return ToText(); }
+ /** @deprecated use ToUnknown()
+ Return the handle as a TiXmlUnknown. This may return null.
+ */
+ TiXmlUnknown* Unknown() const { return ToUnknown(); }
private:
TiXmlNode* node;
};
+
+/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
+
+ -# Print to memory (especially in non-STL mode)
+ -# Control formatting (line endings, etc.)
+
+ When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
+ Before calling Accept() you can call methods to control the printing
+ of the XML document. After TiXmlNode::Accept() is called, the printed document can
+ be accessed via the CStr(), Str(), and Size() methods.
+
+ TiXmlPrinter uses the Visitor API.
+ @verbatim
+ TiXmlPrinter printer;
+ printer.SetIndent( "\t" );
+
+ doc.Accept( &printer );
+ fprintf( stdout, "%s", printer.CStr() );
+ @endverbatim
+*/
+class TiXmlPrinter : public TiXmlVisitor
+{
+public:
+ TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
+ buffer(), indent( " " ), lineBreak( "\n" ) {}
+
+ virtual bool VisitEnter( const TiXmlDocument& doc );
+ virtual bool VisitExit( const TiXmlDocument& doc );
+
+ virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
+ virtual bool VisitExit( const TiXmlElement& element );
+
+ virtual bool Visit( const TiXmlDeclaration& declaration );
+ virtual bool Visit( const TiXmlText& text );
+ virtual bool Visit( const TiXmlComment& comment );
+ virtual bool Visit( const TiXmlUnknown& unknown );
+
+ /** Set the indent characters for printing. By default 4 spaces
+ but tab (\t) is also useful, or null/empty string for no indentation.
+ */
+ void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; }
+ /// Query the indention string.
+ const char* Indent() { return indent.c_str(); }
+ /** Set the line breaking string. By default set to newline (\n).
+ Some operating systems prefer other characters, or can be
+ set to the null/empty string for no indenation.
+ */
+ void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; }
+ /// Query the current line breaking string.
+ const char* LineBreak() { return lineBreak.c_str(); }
+
+ /** Switch over to "stream printing" which is the most dense formatting without
+ linebreaks. Common when the XML is needed for network transmission.
+ */
+ void SetStreamPrinting() { indent = "";
+ lineBreak = "";
+ }
+ /// Return the result.
+ const char* CStr() { return buffer.c_str(); }
+ /// Return the length of the result string.
+ size_t Size() { return buffer.size(); }
+
+ #ifdef TIXML_USE_STL
+ /// Return the result.
+ const std::string& Str() { return buffer; }
+ #endif
+
+private:
+ void DoIndent() {
+ for( int i=0; i<depth; ++i )
+ buffer += indent;
+ }
+ void DoLineBreak() {
+ buffer += lineBreak;
+ }
+
+ int depth;
+ bool simpleTextPrint;
+ TIXML_STRING buffer;
+ TIXML_STRING indent;
+ TIXML_STRING lineBreak;
+};
+
+
#ifdef _MSC_VER
#pragma warning( pop )
#endif
#endif
-