mirror of https://github.com/AxioDL/tinyxml2.git
test cases. Working out attribute interface.
This commit is contained in:
parent
1a1d4a72dd
commit
09a11c5964
108
tinyxml2.cpp
108
tinyxml2.cpp
|
@ -59,7 +59,7 @@ void StrPair::SetStr( const char* str, int flags )
|
||||||
Reset();
|
Reset();
|
||||||
size_t len = strlen( str );
|
size_t len = strlen( str );
|
||||||
start = new char[ len+1 ];
|
start = new char[ len+1 ];
|
||||||
strncpy( start, str, len );
|
memcpy( start, str, len+1 );
|
||||||
end = start + len;
|
end = start + len;
|
||||||
this->flags = flags | NEEDS_DELETE;
|
this->flags = flags | NEEDS_DELETE;
|
||||||
}
|
}
|
||||||
|
@ -341,17 +341,16 @@ XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
||||||
addThis->prev = lastChild;
|
addThis->prev = lastChild;
|
||||||
lastChild = addThis;
|
lastChild = addThis;
|
||||||
|
|
||||||
addThis->parent = this;
|
|
||||||
addThis->next = 0;
|
addThis->next = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TIXMLASSERT( firstChild == 0 );
|
TIXMLASSERT( firstChild == 0 );
|
||||||
firstChild = lastChild = addThis;
|
firstChild = lastChild = addThis;
|
||||||
|
|
||||||
addThis->parent = this;
|
|
||||||
addThis->prev = 0;
|
addThis->prev = 0;
|
||||||
addThis->next = 0;
|
addThis->next = 0;
|
||||||
}
|
}
|
||||||
|
addThis->parent = this;
|
||||||
return addThis;
|
return addThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,17 +365,16 @@ XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis )
|
||||||
addThis->next = firstChild;
|
addThis->next = firstChild;
|
||||||
firstChild = addThis;
|
firstChild = addThis;
|
||||||
|
|
||||||
addThis->parent = this;
|
|
||||||
addThis->prev = 0;
|
addThis->prev = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TIXMLASSERT( lastChild == 0 );
|
TIXMLASSERT( lastChild == 0 );
|
||||||
firstChild = lastChild = addThis;
|
firstChild = lastChild = addThis;
|
||||||
|
|
||||||
addThis->parent = this;
|
|
||||||
addThis->prev = 0;
|
addThis->prev = 0;
|
||||||
addThis->next = 0;
|
addThis->next = 0;
|
||||||
}
|
}
|
||||||
|
addThis->parent = this;
|
||||||
return addThis;
|
return addThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,6 +393,7 @@ XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis )
|
||||||
addThis->next = afterThis->next;
|
addThis->next = afterThis->next;
|
||||||
afterThis->next->prev = addThis;
|
afterThis->next->prev = addThis;
|
||||||
afterThis->next = addThis;
|
afterThis->next = addThis;
|
||||||
|
addThis->parent = this;
|
||||||
return addThis;
|
return addThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,6 +566,12 @@ char* XMLAttribute::ParseDeep( char* p )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLAttribute::SetName( const char* n )
|
||||||
|
{
|
||||||
|
name.SetStr( n );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int XMLAttribute::QueryIntAttribute( int* value ) const
|
int XMLAttribute::QueryIntAttribute( int* value ) const
|
||||||
{
|
{
|
||||||
if ( TIXML_SSCANF( Value(), "%d", value ) == 1 )
|
if ( TIXML_SSCANF( Value(), "%d", value ) == 1 )
|
||||||
|
@ -663,19 +668,18 @@ void XMLAttribute::SetAttribute( float v )
|
||||||
// --------- XMLElement ---------- //
|
// --------- XMLElement ---------- //
|
||||||
XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),
|
XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),
|
||||||
closing( false ),
|
closing( false ),
|
||||||
rootAttribute( 0 ),
|
rootAttribute( 0 )
|
||||||
lastAttribute( 0 )
|
//lastAttribute( 0 )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XMLElement::~XMLElement()
|
XMLElement::~XMLElement()
|
||||||
{
|
{
|
||||||
XMLAttribute* attribute = rootAttribute;
|
while( rootAttribute ) {
|
||||||
while( attribute ) {
|
XMLAttribute* next = rootAttribute->next;
|
||||||
XMLAttribute* next = attribute->next;
|
DELETE_ATTRIBUTE( rootAttribute );
|
||||||
DELETE_ATTRIBUTE( attribute );
|
rootAttribute = next;
|
||||||
attribute = next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,13 +710,29 @@ XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
|
||||||
{
|
{
|
||||||
XMLAttribute* attrib = FindAttribute( name );
|
XMLAttribute* attrib = FindAttribute( name );
|
||||||
if ( !attrib ) {
|
if ( !attrib ) {
|
||||||
attrib = new (document->attributePool.Alloc() ) XMLAttribute( this );
|
attrib = new (document->attributePool.Alloc() ) XMLAttribute( this );
|
||||||
attrib->memPool = &document->attributePool;
|
attrib->memPool = &document->attributePool;
|
||||||
|
LinkAttribute( attrib );
|
||||||
|
attrib->SetName( name );
|
||||||
}
|
}
|
||||||
return attrib;
|
return attrib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLElement::LinkAttribute( XMLAttribute* attrib )
|
||||||
|
{
|
||||||
|
if ( rootAttribute ) {
|
||||||
|
XMLAttribute* end = rootAttribute;
|
||||||
|
while ( end->next )
|
||||||
|
end = end->next;
|
||||||
|
end->next = attrib;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rootAttribute = attrib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char* XMLElement::ParseAttributes( char* p, bool* closedElement )
|
char* XMLElement::ParseAttributes( char* p, bool* closedElement )
|
||||||
{
|
{
|
||||||
const char* start = p;
|
const char* start = p;
|
||||||
|
@ -737,14 +757,7 @@ char* XMLElement::ParseAttributes( char* p, bool* closedElement )
|
||||||
document->SetError( XMLDocument::ERROR_PARSING_ATTRIBUTE, start, p );
|
document->SetError( XMLDocument::ERROR_PARSING_ATTRIBUTE, start, p );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( rootAttribute ) {
|
LinkAttribute( attrib );
|
||||||
TIXMLASSERT( lastAttribute );
|
|
||||||
lastAttribute->next = attrib;
|
|
||||||
lastAttribute = attrib;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rootAttribute = lastAttribute = attrib;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// end of the tag
|
// end of the tag
|
||||||
else if ( *p == '/' && *(p+1) == '>' ) {
|
else if ( *p == '/' && *(p+1) == '>' ) {
|
||||||
|
@ -876,10 +889,10 @@ XMLComment* XMLDocument::NewComment( const char* str )
|
||||||
|
|
||||||
XMLText* XMLDocument::NewText( const char* str )
|
XMLText* XMLDocument::NewText( const char* str )
|
||||||
{
|
{
|
||||||
XMLText* Text = new (textPool.Alloc()) XMLText( this );
|
XMLText* text = new (textPool.Alloc()) XMLText( this );
|
||||||
Text->memPool = &textPool;
|
text->memPool = &textPool;
|
||||||
Text->SetValue( str );
|
text->SetValue( str );
|
||||||
return Text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -923,44 +936,6 @@ void XMLDocument::SetError( int error, const char* str1, const char* str2 )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
StringStack::StringStack()
|
|
||||||
{
|
|
||||||
nPositive = 0;
|
|
||||||
mem.Push( 0 ); // start with null. makes later code simpler.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
StringStack::~StringStack()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void StringStack::Push( const char* str ) {
|
|
||||||
int needed = strlen( str ) + 1;
|
|
||||||
char* p = mem.PushArr( needed );
|
|
||||||
strcpy( p, str );
|
|
||||||
if ( needed > 1 )
|
|
||||||
nPositive++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char* StringStack::Pop() {
|
|
||||||
TIXMLASSERT( mem.Size() > 1 );
|
|
||||||
const char* p = mem.Mem() + mem.Size() - 2; // end of final string.
|
|
||||||
if ( *p ) {
|
|
||||||
nPositive--;
|
|
||||||
}
|
|
||||||
while( *p ) { // stack starts with a null, don't need to check for 'mem'
|
|
||||||
TIXMLASSERT( p > mem.Mem() );
|
|
||||||
--p;
|
|
||||||
}
|
|
||||||
mem.PopArr( strlen(p)+1 );
|
|
||||||
return p+1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
XMLStreamer::XMLStreamer( FILE* file ) : fp( file ), depth( 0 ), elementJustOpened( false ), textDepth( -1 )
|
XMLStreamer::XMLStreamer( FILE* file ) : fp( file ), depth( 0 ), elementJustOpened( false ), textDepth( -1 )
|
||||||
{
|
{
|
||||||
for( int i=0; i<ENTITY_RANGE; ++i ) {
|
for( int i=0; i<ENTITY_RANGE; ++i ) {
|
||||||
|
@ -1094,8 +1069,11 @@ void XMLStreamer::PushComment( const char* comment )
|
||||||
if ( elementJustOpened ) {
|
if ( elementJustOpened ) {
|
||||||
SealElement();
|
SealElement();
|
||||||
}
|
}
|
||||||
PrintSpace( depth );
|
if ( textDepth < 0 && depth > 0) {
|
||||||
fprintf( fp, "<!--%s-->\n", comment );
|
fprintf( fp, "\n" );
|
||||||
|
PrintSpace( depth );
|
||||||
|
}
|
||||||
|
fprintf( fp, "<!--%s-->", comment );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
10
tinyxml2.h
10
tinyxml2.h
|
@ -564,10 +564,12 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum { BUF_SIZE = 200 };
|
enum { BUF_SIZE = 200 };
|
||||||
|
|
||||||
XMLAttribute( XMLElement* element ) : next( 0 ) {}
|
XMLAttribute( XMLElement* element ) : next( 0 ) {}
|
||||||
virtual ~XMLAttribute() {}
|
virtual ~XMLAttribute() {}
|
||||||
XMLAttribute( const XMLAttribute& ); // not supported
|
XMLAttribute( const XMLAttribute& ); // not supported
|
||||||
void operator=( const XMLAttribute& ); // not supported
|
void operator=( const XMLAttribute& ); // not supported
|
||||||
|
void SetName( const char* name );
|
||||||
|
|
||||||
char* ParseDeep( char* p );
|
char* ParseDeep( char* p );
|
||||||
|
|
||||||
|
@ -592,6 +594,12 @@ public:
|
||||||
|
|
||||||
const char* Attribute( const char* name ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return 0; return a->Value(); }
|
const char* Attribute( const char* name ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return 0; return a->Value(); }
|
||||||
|
|
||||||
|
int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( name, &i ); return i; }
|
||||||
|
unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( name, &i ); return i; }
|
||||||
|
bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( name, &b ); return b; }
|
||||||
|
double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( name, &d ); return d; }
|
||||||
|
float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( name, &f ); return f; }
|
||||||
|
|
||||||
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->QueryIntAttribute( value ); }
|
||||||
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->QueryUnsignedAttribute( value ); }
|
||||||
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->QueryBoolAttribute( value ); }
|
||||||
|
@ -623,11 +631,11 @@ private:
|
||||||
|
|
||||||
XMLAttribute* FindAttribute( const char* name );
|
XMLAttribute* FindAttribute( const char* name );
|
||||||
XMLAttribute* FindOrCreateAttribute( const char* name );
|
XMLAttribute* FindOrCreateAttribute( const char* name );
|
||||||
|
void LinkAttribute( XMLAttribute* attrib );
|
||||||
char* ParseAttributes( char* p, bool *closedElement );
|
char* ParseAttributes( char* p, bool *closedElement );
|
||||||
|
|
||||||
bool closing;
|
bool closing;
|
||||||
XMLAttribute* rootAttribute;
|
XMLAttribute* rootAttribute;
|
||||||
XMLAttribute* lastAttribute; // fixme: remove
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
17
xmltest.cpp
17
xmltest.cpp
|
@ -14,7 +14,7 @@ using namespace tinyxml2;
|
||||||
int gPass = 0;
|
int gPass = 0;
|
||||||
int gFail = 0;
|
int gFail = 0;
|
||||||
|
|
||||||
bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho )
|
bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true )
|
||||||
{
|
{
|
||||||
bool pass = !strcmp( expected, found );
|
bool pass = !strcmp( expected, found );
|
||||||
if ( pass )
|
if ( pass )
|
||||||
|
@ -22,7 +22,7 @@ bool XmlTest (const char* testString, const char* expected, const char* found, b
|
||||||
else
|
else
|
||||||
printf ("[fail]");
|
printf ("[fail]");
|
||||||
|
|
||||||
if ( noEcho )
|
if ( !echo )
|
||||||
printf (" %s\n", testString);
|
printf (" %s\n", testString);
|
||||||
else
|
else
|
||||||
printf (" %s [%s][%s]\n", testString, expected, found);
|
printf (" %s [%s][%s]\n", testString, expected, found);
|
||||||
|
@ -35,7 +35,7 @@ bool XmlTest (const char* testString, const char* expected, const char* found, b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool XmlTest( const char* testString, int expected, int found, bool noEcho )
|
bool XMLTest( const char* testString, int expected, int found, bool echo=true )
|
||||||
{
|
{
|
||||||
bool pass = ( expected == found );
|
bool pass = ( expected == found );
|
||||||
if ( pass )
|
if ( pass )
|
||||||
|
@ -43,7 +43,7 @@ bool XmlTest( const char* testString, int expected, int found, bool noEcho )
|
||||||
else
|
else
|
||||||
printf ("[fail]");
|
printf ("[fail]");
|
||||||
|
|
||||||
if ( noEcho )
|
if ( !echo )
|
||||||
printf (" %s\n", testString);
|
printf (" %s\n", testString);
|
||||||
else
|
else
|
||||||
printf (" %s [%d][%d]\n", testString, expected, found);
|
printf (" %s [%d][%d]\n", testString, expected, found);
|
||||||
|
@ -126,7 +126,7 @@ int main( int argc, const char* argv )
|
||||||
// <!--comment-->
|
// <!--comment-->
|
||||||
// <sub attrib="1" />
|
// <sub attrib="1" />
|
||||||
// <sub attrib="2" />
|
// <sub attrib="2" />
|
||||||
// <sub attrib="3" >With Text!</sub>
|
// <sub attrib="3" >& Text!</sub>
|
||||||
// <element>
|
// <element>
|
||||||
|
|
||||||
XMLDocument* doc = new XMLDocument();
|
XMLDocument* doc = new XMLDocument();
|
||||||
|
@ -140,8 +140,13 @@ int main( int argc, const char* argv )
|
||||||
XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
|
XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
|
||||||
element->InsertAfterChild( comment, sub[0] );
|
element->InsertAfterChild( comment, sub[0] );
|
||||||
element->InsertAfterChild( sub[0], sub[1] );
|
element->InsertAfterChild( sub[0], sub[1] );
|
||||||
sub[2]->InsertFirstChild( doc->NewText( "With Text!" ));
|
sub[2]->InsertFirstChild( doc->NewText( "& Text!" ));
|
||||||
doc->Print();
|
doc->Print();
|
||||||
|
XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() );
|
||||||
|
XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) );
|
||||||
|
XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
|
||||||
|
XMLTest( "Programmatic DOM", "& Text!",
|
||||||
|
doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
|
||||||
delete doc;
|
delete doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue