Patching up incorrect boilerplate code. Added clone/equal methods.

This commit is contained in:
Lee Thomason 2012-02-27 17:54:22 -08:00
parent 5ce4d97945
commit 7d00b9ab95
3 changed files with 306 additions and 30 deletions

View File

@ -402,12 +402,15 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
static const int cdataHeaderLen = 9; static const int cdataHeaderLen = 9;
static const int elementHeaderLen = 1; static const int elementHeaderLen = 1;
#if defined(_MSC_VER)
#pragma warning ( push ) #pragma warning ( push )
#pragma warning ( disable : 4127 ) #pragma warning ( disable : 4127 )
#endif
TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool
TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool
#if defined(_MSC_VER)
#pragma warning (pop) #pragma warning (pop)
#endif
if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) { if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {
returnNode = new (commentPool.Alloc()) XMLDeclaration( this ); returnNode = new (commentPool.Alloc()) XMLDeclaration( this );
returnNode->memPool = &commentPool; returnNode->memPool = &commentPool;
@ -622,6 +625,32 @@ const XMLElement* XMLNode::LastChildElement( const char* value ) const
} }
const XMLElement* XMLNode::NextSiblingElement( const char* value ) const
{
for( XMLNode* element=this->next; element; element = element->next ) {
if ( element->ToElement()
&& (!value || XMLUtil::StringEqual( value, element->Value() )))
{
return element->ToElement();
}
}
return 0;
}
const XMLElement* XMLNode::PreviousSiblingElement( const char* value ) const
{
for( XMLNode* element=this->prev; element; element = element->prev ) {
if ( element->ToElement()
&& (!value || XMLUtil::StringEqual( value, element->Value() )))
{
return element->ToElement();
}
}
return 0;
}
char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) char* XMLNode::ParseDeep( char* p, StrPair* parentEnd )
{ {
// This is a recursive method, but thinking about it "at the current level" // This is a recursive method, but thinking about it "at the current level"
@ -723,6 +752,23 @@ char* XMLText::ParseDeep( char* p, StrPair* )
} }
XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const
{
if ( !doc ) {
doc = document;
}
XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern?
text->SetCData( this->CData() );
return text;
}
bool XMLText::ShallowEqual( const XMLNode* compare ) const
{
return ( compare->ToText() && XMLUtil::StringEqual( compare->ToText()->Value(), Value() ));
}
bool XMLText::Accept( XMLVisitor* visitor ) const bool XMLText::Accept( XMLVisitor* visitor ) const
{ {
return visitor->Visit( *this ); return visitor->Visit( *this );
@ -754,6 +800,22 @@ char* XMLComment::ParseDeep( char* p, StrPair* )
} }
XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const
{
if ( !doc ) {
doc = document;
}
XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern?
return comment;
}
bool XMLComment::ShallowEqual( const XMLNode* compare ) const
{
return ( compare->ToComment() && XMLUtil::StringEqual( compare->ToComment()->Value(), Value() ));
}
bool XMLComment::Accept( XMLVisitor* visitor ) const bool XMLComment::Accept( XMLVisitor* visitor ) const
{ {
return visitor->Visit( *this ); return visitor->Visit( *this );
@ -785,6 +847,23 @@ char* XMLDeclaration::ParseDeep( char* p, StrPair* )
} }
XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const
{
if ( !doc ) {
doc = document;
}
XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern?
return dec;
}
bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const
{
return ( compare->ToDeclaration() && XMLUtil::StringEqual( compare->ToDeclaration()->Value(), Value() ));
}
bool XMLDeclaration::Accept( XMLVisitor* visitor ) const bool XMLDeclaration::Accept( XMLVisitor* visitor ) const
{ {
return visitor->Visit( *this ); return visitor->Visit( *this );
@ -815,6 +894,22 @@ char* XMLUnknown::ParseDeep( char* p, StrPair* )
} }
XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const
{
if ( !doc ) {
doc = document;
}
XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern?
return text;
}
bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const
{
return ( compare->ToUnknown() && XMLUtil::StringEqual( compare->ToUnknown()->Value(), Value() ));
}
bool XMLUnknown::Accept( XMLVisitor* visitor ) const bool XMLUnknown::Accept( XMLVisitor* visitor ) const
{ {
return visitor->Visit( *this ); return visitor->Visit( *this );
@ -840,7 +935,7 @@ void XMLAttribute::SetName( const char* n )
} }
int XMLAttribute::QueryIntAttribute( int* value ) const int XMLAttribute::QueryIntValue( int* value ) const
{ {
if ( TIXML_SSCANF( Value(), "%d", value ) == 1 ) if ( TIXML_SSCANF( Value(), "%d", value ) == 1 )
return XML_NO_ERROR; return XML_NO_ERROR;
@ -848,7 +943,7 @@ int XMLAttribute::QueryIntAttribute( int* value ) const
} }
int XMLAttribute::QueryUnsignedAttribute( unsigned int* value ) const int XMLAttribute::QueryUnsignedValue( unsigned int* value ) const
{ {
if ( TIXML_SSCANF( Value(), "%u", value ) == 1 ) if ( TIXML_SSCANF( Value(), "%u", value ) == 1 )
return XML_NO_ERROR; return XML_NO_ERROR;
@ -856,10 +951,10 @@ int XMLAttribute::QueryUnsignedAttribute( unsigned int* value ) const
} }
int XMLAttribute::QueryBoolAttribute( bool* value ) const int XMLAttribute::QueryBoolValue( bool* value ) const
{ {
int ival = -1; int ival = -1;
QueryIntAttribute( &ival ); QueryIntValue( &ival );
if ( ival > 0 || XMLUtil::StringEqual( Value(), "true" ) ) { if ( ival > 0 || XMLUtil::StringEqual( Value(), "true" ) ) {
*value = true; *value = true;
@ -873,7 +968,7 @@ int XMLAttribute::QueryBoolAttribute( bool* value ) const
} }
int XMLAttribute::QueryDoubleAttribute( double* value ) const int XMLAttribute::QueryDoubleValue( double* value ) const
{ {
if ( TIXML_SSCANF( Value(), "%lf", value ) == 1 ) if ( TIXML_SSCANF( Value(), "%lf", value ) == 1 )
return XML_NO_ERROR; return XML_NO_ERROR;
@ -881,7 +976,7 @@ int XMLAttribute::QueryDoubleAttribute( double* value ) const
} }
int XMLAttribute::QueryFloatAttribute( float* value ) const int XMLAttribute::QueryFloatValue( float* value ) const
{ {
if ( TIXML_SSCANF( Value(), "%f", value ) == 1 ) if ( TIXML_SSCANF( Value(), "%f", value ) == 1 )
return XML_NO_ERROR; return XML_NO_ERROR;
@ -1103,6 +1198,43 @@ char* XMLElement::ParseDeep( char* p, StrPair* strPair )
} }
XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const
{
if ( !doc ) {
doc = document;
}
XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern?
for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) {
element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern?
}
return element;
}
bool XMLElement::ShallowEqual( const XMLNode* compare ) const
{
const XMLElement* other = compare->ToElement();
if ( other && XMLUtil::StringEqual( other->Value(), Value() )) {
const XMLAttribute* a=FirstAttribute();
const XMLAttribute* b=other->FirstAttribute();
while ( a && b ) {
if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) {
return false;
}
}
if ( a || b ) {
// different count
return false;
}
return true;
}
return false;
}
bool XMLElement::Accept( XMLVisitor* visitor ) const bool XMLElement::Accept( XMLVisitor* visitor ) const
{ {
if ( visitor->VisitEnter( *this, rootAttribute ) ) if ( visitor->VisitEnter( *this, rootAttribute ) )
@ -1114,9 +1246,9 @@ bool XMLElement::Accept( XMLVisitor* visitor ) const
} }
} }
return visitor->VisitExit( *this ); return visitor->VisitExit( *this );
} }
// --------- XMLDocument ----------- // // --------- XMLDocument ----------- //
XMLDocument::XMLDocument() : XMLDocument::XMLDocument() :
XMLNode( 0 ), XMLNode( 0 ),
@ -1185,15 +1317,37 @@ XMLText* XMLDocument::NewText( const char* str )
} }
XMLDeclaration* XMLDocument::NewDeclaration( const char* str )
{
XMLDeclaration* dec = new (commentPool.Alloc()) XMLDeclaration( this );
dec->memPool = &commentPool;
dec->SetValue( str );
return dec;
}
XMLUnknown* XMLDocument::NewUnknown( const char* str )
{
XMLUnknown* unk = new (commentPool.Alloc()) XMLUnknown( this );
unk->memPool = &commentPool;
unk->SetValue( str );
return unk;
}
int XMLDocument::LoadFile( const char* filename ) int XMLDocument::LoadFile( const char* filename )
{ {
DeleteChildren(); DeleteChildren();
InitDocument(); InitDocument();
#if defined(_MSC_VER)
#pragma warning ( push ) #pragma warning ( push )
#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
#endif
FILE* fp = fopen( filename, "rb" ); FILE* fp = fopen( filename, "rb" );
#if defined(_MSC_VER)
#pragma warning ( pop ) #pragma warning ( pop )
#endif
if ( !fp ) { if ( !fp ) {
SetError( ERROR_FILE_NOT_FOUND, filename, 0 ); SetError( ERROR_FILE_NOT_FOUND, filename, 0 );
return errorID; return errorID;
@ -1236,10 +1390,14 @@ int XMLDocument::LoadFile( FILE* fp )
void XMLDocument::SaveFile( const char* filename ) void XMLDocument::SaveFile( const char* filename )
{ {
#if defined(_MSC_VER)
#pragma warning ( push ) #pragma warning ( push )
#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
#endif
FILE* fp = fopen( filename, "w" ); FILE* fp = fopen( filename, "w" );
#if defined(_MSC_VER)
#pragma warning ( pop ) #pragma warning ( pop )
#endif
XMLPrinter stream( fp ); XMLPrinter stream( fp );
Print( &stream ); Print( &stream );
fclose( fp ); fclose( fp );
@ -1452,6 +1610,38 @@ void XMLPrinter::PushAttribute( const char* name, const char* value )
} }
void XMLPrinter::PushAttribute( const char* name, int v )
{
char buf[BUF_SIZE];
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v );
PushAttribute( name, buf );
}
void XMLPrinter::PushAttribute( const char* name, unsigned v )
{
char buf[BUF_SIZE];
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%u", v );
PushAttribute( name, buf );
}
void XMLPrinter::PushAttribute( const char* name, bool v )
{
char buf[BUF_SIZE];
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v ? 1 : 0 );
PushAttribute( name, buf );
}
void XMLPrinter::PushAttribute( const char* name, double v )
{
char buf[BUF_SIZE];
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v );
PushAttribute( name, buf );
}
void XMLPrinter::CloseElement() void XMLPrinter::CloseElement()
{ {
--depth; --depth;

View File

@ -21,7 +21,7 @@ must not be misrepresented as being the original software.
distribution. distribution.
*/ */
#ifndef TINYXML_INCLUDED #ifndef TINYXML2_INCLUDED
#define TINYXML2_INCLUDED #define TINYXML2_INCLUDED
@ -30,8 +30,9 @@ distribution.
#include <stdio.h> #include <stdio.h>
#include <memory.h> #include <memory.h>
/* TODO: create main page description. /*
TODO: add 'lastAttribute' for faster parsing. TODO: add 'lastAttribute' for faster parsing.
TODO: intern strings instead of allocation.
*/ */
/* /*
gcc: g++ -Wall tinyxml2.cpp xmltest.cpp -o gccxmltest.exe gcc: g++ -Wall tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
@ -482,16 +483,16 @@ public:
XMLNode* PreviousSibling() { return prev; } XMLNode* PreviousSibling() { return prev; }
/// Get the previous (left) sibling element of this node, with an opitionally supplied name. /// Get the previous (left) sibling element of this node, with an opitionally supplied name.
const XMLNode* PreviousSiblingElement( const char* value=0 ) const ; const XMLElement* PreviousSiblingElement( const char* value=0 ) const ;
XMLNode* PreviousSiblingElement( const char* value=0 ) { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( value ) ); } XMLElement* PreviousSiblingElement( const char* value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( value ) ); }
/// Get the next (right) sibling node of this node. /// Get the next (right) sibling node of this node.
const XMLNode* NextSibling() const { return next; } const XMLNode* NextSibling() const { return next; }
XMLNode* NextSibling() { return next; } XMLNode* NextSibling() { return next; }
/// Get the next (right) sibling element of this node, with an opitionally supplied name. /// Get the next (right) sibling element of this node, with an opitionally supplied name.
const XMLNode* NextSiblingElement( const char* value=0 ) const; const XMLElement* NextSiblingElement( const char* value=0 ) const;
XMLNode* NextSiblingElement( const char* value=0 ) { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->NextSiblingElement( value ) ); } XMLElement* NextSiblingElement( const char* value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( value ) ); }
/** /**
Add a child node as the last (right) child. Add a child node as the last (right) child.
@ -516,6 +517,25 @@ public:
*/ */
void DeleteChild( XMLNode* node ); void DeleteChild( XMLNode* node );
/**
Make a copy of this node, but not its children.
You may pass in a Document pointer that will be
the owner of the new Node. If the 'document' is
null, then the node returned will be allocated
from the current Document. (this->GetDocument())
Note: if called on a XMLDocument, this will return null.
*/
virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
/**
Test if 2 nodes are the same, but don't test children.
The 2 nodes do not need to be in the same Document.
Note: if called on a XMLDocument, this will return false.
*/
virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the /** 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 XML tree will be conditionally visited and the host will be called back
via the TiXmlVisitor interface. via the TiXmlVisitor interface.
@ -593,6 +613,9 @@ public:
bool CData() const { return isCData; } bool CData() const { return isCData; }
char* ParseDeep( char*, StrPair* endTag ); char* ParseDeep( char*, StrPair* endTag );
virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const;
protected: protected:
XMLText( XMLDocument* doc ) : XMLNode( doc ), isCData( false ) {} XMLText( XMLDocument* doc ) : XMLNode( doc ), isCData( false ) {}
@ -616,6 +639,8 @@ public:
virtual bool Accept( XMLVisitor* visitor ) const; virtual bool Accept( XMLVisitor* visitor ) const;
char* ParseDeep( char*, StrPair* endTag ); char* ParseDeep( char*, StrPair* endTag );
virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const;
protected: protected:
XMLComment( XMLDocument* doc ); XMLComment( XMLDocument* doc );
@ -648,6 +673,8 @@ public:
virtual bool Accept( XMLVisitor* visitor ) const; virtual bool Accept( XMLVisitor* visitor ) const;
char* ParseDeep( char*, StrPair* endTag ); char* ParseDeep( char*, StrPair* endTag );
virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const;
protected: protected:
XMLDeclaration( XMLDocument* doc ); XMLDeclaration( XMLDocument* doc );
@ -674,6 +701,8 @@ public:
virtual bool Accept( XMLVisitor* visitor ) const; virtual bool Accept( XMLVisitor* visitor ) const;
char* ParseDeep( char*, StrPair* endTag ); char* ParseDeep( char*, StrPair* endTag );
virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const;
protected: protected:
XMLUnknown( XMLDocument* doc ); XMLUnknown( XMLDocument* doc );
@ -685,6 +714,7 @@ protected:
enum { enum {
XML_NO_ERROR = 0, XML_NO_ERROR = 0,
XML_SUCCESS = 0,
NO_ATTRIBUTE, NO_ATTRIBUTE,
WRONG_ATTRIBUTE_TYPE, WRONG_ATTRIBUTE_TYPE,
@ -723,29 +753,29 @@ public:
If the value isn't an integer, 0 will be returned. There is no error checking; If the value isn't an integer, 0 will be returned. There is no error checking;
use QueryIntAttribute() if you need error checking. use QueryIntAttribute() if you need error checking.
*/ */
int IntAttribute() const { int i=0; QueryIntAttribute( &i ); return i; } int IntValue() const { int i=0; QueryIntValue( &i ); return i; }
/// Query as an unsigned integer. See IntAttribute() /// Query as an unsigned integer. See IntAttribute()
unsigned UnsignedAttribute() const { unsigned i=0; QueryUnsignedAttribute( &i ); return i; } unsigned UnsignedValue() const { unsigned i=0; QueryUnsignedValue( &i ); return i; }
/// Query as a boolean. See IntAttribute() /// Query as a boolean. See IntAttribute()
bool BoolAttribute() const { bool b=false; QueryBoolAttribute( &b ); return b; } bool BoolValue() const { bool b=false; QueryBoolValue( &b ); return b; }
/// Query as a double. See IntAttribute() /// Query as a double. See IntAttribute()
double DoubleAttribute() const { double d=0; QueryDoubleAttribute( &d ); return d; } double DoubleValue() const { double d=0; QueryDoubleValue( &d ); return d; }
/// Query as a float. See IntAttribute() /// Query as a float. See IntAttribute()
float FloatAttribute() const { float f=0; QueryFloatAttribute( &f ); return f; } float FloatValue() const { float f=0; QueryFloatValue( &f ); return f; }
/** QueryIntAttribute interprets the attribute as an integer, and returns the value /** QueryIntAttribute interprets the attribute as an integer, and returns the value
in the provided paremeter. The function will return XML_NO_ERROR on success, in the provided paremeter. The function will return XML_NO_ERROR on success,
and WRONG_ATTRIBUTE_TYPE if the conversion is not successful. and WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
*/ */
int QueryIntAttribute( int* value ) const; int QueryIntValue( int* value ) const;
/// See QueryIntAttribute /// See QueryIntAttribute
int QueryUnsignedAttribute( unsigned int* value ) const; int QueryUnsignedValue( unsigned int* value ) const;
/// See QueryIntAttribute /// See QueryIntAttribute
int QueryBoolAttribute( bool* value ) const; int QueryBoolValue( bool* value ) const;
/// See QueryIntAttribute /// See QueryIntAttribute
int QueryDoubleAttribute( double* value ) const; int QueryDoubleValue( double* value ) const;
/// See QueryIntAttribute /// See QueryIntAttribute
int QueryFloatAttribute( float* value ) const; int QueryFloatValue( float* value ) const;
/// Set the attribute to a string value. /// Set the attribute to a string value.
void SetAttribute( const char* value ); void SetAttribute( const char* value );
@ -829,15 +859,15 @@ public:
QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
@endverbatim @endverbatim
*/ */
int QueryIntAttribute( const char* name, int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryIntAttribute( value ); } int QueryIntAttribute( const char* name, int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryIntValue( value ); }
/// See QueryIntAttribute() /// See QueryIntAttribute()
int QueryUnsignedAttribute( const char* name, unsigned int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryUnsignedAttribute( value ); } int QueryUnsignedAttribute( const char* name, unsigned int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryUnsignedValue( value ); }
/// See QueryIntAttribute() /// See QueryIntAttribute()
int QueryBoolAttribute( const char* name, bool* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryBoolAttribute( value ); } int QueryBoolAttribute( const char* name, bool* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryBoolValue( value ); }
/// See QueryIntAttribute() /// See QueryIntAttribute()
int QueryDoubleAttribute( const char* name, double* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryDoubleAttribute( value ); } int QueryDoubleAttribute( const char* name, double* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryDoubleValue( value ); }
/// See QueryIntAttribute() /// See QueryIntAttribute()
int QueryFloatAttribute( const char* name, float* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryFloatAttribute( value ); } int QueryFloatAttribute( const char* name, float* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryFloatValue( value ); }
/// Sets the named attribute to value. /// Sets the named attribute to value.
void SetAttribute( const char* name, const char* value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); } void SetAttribute( const char* name, const char* value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
@ -898,6 +928,8 @@ public:
}; };
int ClosingType() const { return closingType; } int ClosingType() const { return closingType; }
char* ParseDeep( char* p, StrPair* endTag ); char* ParseDeep( char* p, StrPair* endTag );
virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const;
private: private:
XMLElement( XMLDocument* doc ); XMLElement( XMLDocument* doc );
@ -999,6 +1031,18 @@ public:
is managed by the Document. is managed by the Document.
*/ */
XMLText* NewText( const char* text ); XMLText* NewText( const char* text );
/**
Create a new Declaration associated with
this Document. The memory for the object
is managed by the Document.
*/
XMLDeclaration* NewDeclaration( const char* text );
/**
Create a new Unknown associated with
this Document. The memory for the object
is managed by the Document.
*/
XMLUnknown* NewUnknown( const char* text );
/** /**
Delete a node associated with this documented. Delete a node associated with this documented.
@ -1022,6 +1066,9 @@ public:
// internal // internal
char* Identify( char* p, XMLNode** node ); char* Identify( char* p, XMLNode** node );
virtual XMLNode* ShallowClone( XMLDocument* document ) const { return 0; }
virtual bool ShallowEqual( const XMLNode* compare ) const { return false; }
private: private:
XMLDocument( const XMLDocument& ); // not supported XMLDocument( const XMLDocument& ); // not supported
void operator=( const XMLDocument& ); // not supported void operator=( const XMLDocument& ); // not supported
@ -1101,6 +1148,10 @@ public:
void OpenElement( const char* name ); void OpenElement( const char* name );
/// If streaming, add an attribute to an open element. /// If streaming, add an attribute to an open element.
void PushAttribute( const char* name, const char* value ); void PushAttribute( const char* name, const char* value );
void PushAttribute( const char* name, int value );
void PushAttribute( const char* name, unsigned value );
void PushAttribute( const char* name, bool value );
void PushAttribute( const char* name, double value );
/// If streaming, close the Element. /// If streaming, close the Element.
void CloseElement(); void CloseElement();
@ -1142,7 +1193,8 @@ private:
int textDepth; int textDepth;
enum { enum {
ENTITY_RANGE = 64 ENTITY_RANGE = 64,
BUF_SIZE = 200
}; };
bool entityFlag[ENTITY_RANGE]; bool entityFlag[ENTITY_RANGE];
bool restrictedEntityFlag[ENTITY_RANGE]; bool restrictedEntityFlag[ENTITY_RANGE];

View File

@ -302,11 +302,15 @@ int main( int /*argc*/, const char* /*argv*/ )
int okay = 0; int okay = 0;
#if defined(_MSC_VER)
#pragma warning ( push ) #pragma warning ( push )
#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
#endif
FILE* saved = fopen( "utf8testout.xml", "r" ); FILE* saved = fopen( "utf8testout.xml", "r" );
FILE* verify = fopen( "utf8testverify.xml", "r" ); FILE* verify = fopen( "utf8testverify.xml", "r" );
#if defined(_MSC_VER)
#pragma warning ( pop ) #pragma warning ( pop )
#endif
if ( saved && verify ) if ( saved && verify )
{ {
@ -419,20 +423,28 @@ int main( int /*argc*/, const char* /*argv*/ )
XMLTest( "Entity transformation: read. ", expected, context, true ); XMLTest( "Entity transformation: read. ", expected, context, true );
#if defined(_MSC_VER)
#pragma warning ( push ) #pragma warning ( push )
#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
#endif
FILE* textfile = fopen( "textfile.txt", "w" ); FILE* textfile = fopen( "textfile.txt", "w" );
#if defined(_MSC_VER)
#pragma warning ( pop ) #pragma warning ( pop )
#endif
if ( textfile ) if ( textfile )
{ {
XMLPrinter streamer( textfile ); XMLPrinter streamer( textfile );
psg->Accept( &streamer ); psg->Accept( &streamer );
fclose( textfile ); fclose( textfile );
} }
#if defined(_MSC_VER)
#pragma warning ( push ) #pragma warning ( push )
#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
#endif
textfile = fopen( "textfile.txt", "r" ); textfile = fopen( "textfile.txt", "r" );
#if defined(_MSC_VER)
#pragma warning ( pop ) #pragma warning ( pop )
#endif
TIXMLASSERT( textfile ); TIXMLASSERT( textfile );
if ( textfile ) if ( textfile )
{ {
@ -618,6 +630,28 @@ int main( int /*argc*/, const char* /*argv*/ )
XMLTest( "Infinite loop test.", true, true ); XMLTest( "Infinite loop test.", true, true );
} }
#endif #endif
{
const char* pub = "<?xml version='1.0'?> <element><sub/></element> <!--comment--> <!DOCTYPE>";
XMLDocument doc;
doc.Parse( pub );
XMLDocument clone;
for( const XMLNode* node=doc.FirstChild(); node; node=node->NextSibling() ) {
XMLNode* copy = node->ShallowClone( &clone );
clone.InsertEndChild( copy );
}
clone.Print();
int count=0;
const XMLNode* a=clone.FirstChild();
const XMLNode* b=doc.FirstChild();
for( ; a && b; a=a->NextSibling(), b=b->NextSibling() ) {
++count;
XMLTest( "Clone and Equal", true, a->ShallowEqual( b ));
}
XMLTest( "Clone and Equal", 4, count );
}
#if defined( _MSC_VER ) #if defined( _MSC_VER )
_CrtMemCheckpoint( &endMemState ); _CrtMemCheckpoint( &endMemState );