From 3ffdd39dbf44c8a9dc40bbc74cebd747a8d93c94 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Wed, 28 Mar 2012 17:27:55 -0700 Subject: [PATCH] handles wip --- tinyxml2.h | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/tinyxml2.h b/tinyxml2.h index 250ce79..7f6e611 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1130,6 +1130,111 @@ private: }; +/** + A XMLHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that XMLHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim +*/ +class XMLHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + //XMLHandle( XMLNode* _node ) { node = _node; } + XMLHandle( const XMLNode* _node ) { node = const_cast(_node); } + //XMLHandle( XMLNode& _node ) { node = &_node; } + XMLHandle( const XMLNode& _node ) { node = const_cast(&_node); } + XMLHandle( const XMLHandle& ref ) { node = ref.node; } + + XMLHandle operator=( XMLHandle ref ) { node = ref.node; return *this; } + + XMLHandle FirstChild() { return XMLHandle( node ? node->FirstChild() : static_cast(0) ); } + const XMLHandle FirstChild() const { return XMLHandle( node ? node->FirstChild() : 0 ); } + + XMLHandle FirstChildElement( const char* value=0 ) { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); } + const XMLHandle FirstChildElement( const char* value=0 ) const { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); } + + XMLHandle LastChild() { return XMLHandle( node ? node->LastChild() : 0 ); } + const XMLHandle LastChild() const { return XMLHandle( node ? node->LastChild() : 0 ); } + + XMLHandle LastChildElement( const char* _value=0 ) { return XMLHandle( node ? node->LastChildElement() : 0 ); } + const XMLHandle LastChildElement( const char* _value=0 ) const { return XMLHandle( node ? node->LastChildElement() : 0 ); } + + XMLHandle PreviousSibling() { return XMLHandle( node ? node->PreviousSibling() : 0 ); } + const XMLHandle PreviousSibling() const { return XMLHandle( node ? node->PreviousSibling() : 0 ); } + + XMLHandle PreviousSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->PreviousSiblingElement() : 0 ); } + const XMLHandle PreviousSiblingElement( const char* _value=0 ) const { return XMLHandle( node ? node->PreviousSiblingElement() : 0 ); } + + XMLHandle NextSibling() { return XMLHandle( node ? node->NextSibling() : 0 ); } + const XMLHandle NextSibling() const { return XMLHandle( node ? node->NextSibling() : 0 ); } + + XMLHandle NextSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); } + const XMLHandle NextSiblingElement( const char* _value=0 ) const { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); } + + + XMLNode* ToNode() { return node; } + const XMLNode* ToNode() const { return node; } + XMLElement* ToElement() { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + const XMLElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + XMLText* ToText() { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + const XMLText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + XMLUnknown* ToUnknown() { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + const XMLUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + XMLDeclaration* ToDeclaration() { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); } + const XMLDeclaration* ToDeclaration() const { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); } + +private: + XMLNode* node; +}; + /** Printing functionality. The XMLPrinter gives you more