Updated TinyXML to v2.6.2

This commit is contained in:
vsonnier 2016-06-06 19:37:55 +02:00
parent 26e61f87a7
commit ca0102b3aa
8 changed files with 449 additions and 369 deletions

View File

@ -1,6 +1,5 @@
/* /*
www.sourceforge.net/projects/tinyxml www.sourceforge.net/projects/tinyxml
Original file by Yves Berquin.
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any warranty. In no event will the authors be held liable for any
@ -22,10 +21,6 @@ must not be misrepresented as being the original software.
distribution. distribution.
*/ */
/*
* THIS FILE WAS ALTERED BY Tyge L?vset, 7. April 2005.
*/
#ifndef TIXML_USE_STL #ifndef TIXML_USE_STL

View File

@ -1,6 +1,5 @@
/* /*
www.sourceforge.net/projects/tinyxml www.sourceforge.net/projects/tinyxml
Original file by Yves Berquin.
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any warranty. In no event will the authors be held liable for any
@ -22,17 +21,6 @@ must not be misrepresented as being the original software.
distribution. distribution.
*/ */
/*
* THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
*
* - completely rewritten. compact, clean, and fast implementation.
* - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
* - fixed reserve() to work as per specification.
* - fixed buggy compares operator==(), operator<(), and operator>()
* - fixed operator+=() to take a const ref argument, following spec.
* - added "copy" constructor with length, and most compare operators.
* - added swap(), clear(), size(), capacity(), operator+().
*/
#ifndef TIXML_USE_STL #ifndef TIXML_USE_STL
@ -106,13 +94,11 @@ class TiXmlString
quit(); quit();
} }
// = operator
TiXmlString& operator = (const char * copy) TiXmlString& operator = (const char * copy)
{ {
return assign( copy, (size_type)strlen(copy)); return assign( copy, (size_type)strlen(copy));
} }
// = operator
TiXmlString& operator = (const TiXmlString & copy) TiXmlString& operator = (const TiXmlString & copy)
{ {
return assign(copy.start(), copy.length()); return assign(copy.start(), copy.length());

View File

@ -1,6 +1,6 @@
/* /*
www.sourceforge.net/projects/tinyxml www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) Original code by Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any warranty. In no event will the authors be held liable for any
@ -31,6 +31,7 @@ distribution.
#include "tinyxml.h" #include "tinyxml.h"
FILE* TiXmlFOpen( const char* filename, const char* mode );
bool TiXmlBase::condenseWhiteSpace = true; bool TiXmlBase::condenseWhiteSpace = true;
@ -161,6 +162,7 @@ void TiXmlNode::CopyTo( TiXmlNode* target ) const
{ {
target->SetValue (value.c_str() ); target->SetValue (value.c_str() );
target->userData = userData; target->userData = userData;
target->location = location;
} }
@ -186,10 +188,11 @@ TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
assert( node->parent == 0 || node->parent == this ); assert( node->parent == 0 || node->parent == this );
assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
if ( node->Type() == TiXmlNode::DOCUMENT ) if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
{ {
delete node; delete node;
if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0; return 0;
} }
@ -210,9 +213,10 @@ TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
{ {
if ( addThis.Type() == TiXmlNode::DOCUMENT ) if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
{ {
if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0; return 0;
} }
TiXmlNode* node = addThis.Clone(); TiXmlNode* node = addThis.Clone();
@ -228,9 +232,10 @@ TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode&
if ( !beforeThis || beforeThis->parent != this ) { if ( !beforeThis || beforeThis->parent != this ) {
return 0; return 0;
} }
if ( addThis.Type() == TiXmlNode::DOCUMENT ) if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
{ {
if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0; return 0;
} }
@ -260,9 +265,10 @@ TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& a
if ( !afterThis || afterThis->parent != this ) { if ( !afterThis || afterThis->parent != this ) {
return 0; return 0;
} }
if ( addThis.Type() == TiXmlNode::DOCUMENT ) if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
{ {
if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0; return 0;
} }
@ -289,9 +295,20 @@ TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& a
TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
{ {
if ( !replaceThis )
return 0;
if ( replaceThis->parent != this ) if ( replaceThis->parent != this )
return 0; return 0;
if ( withThis.ToDocument() ) {
// A document can never be a child. Thanks to Noam.
TiXmlDocument* document = GetDocument();
if ( document )
document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
TiXmlNode* node = withThis.Clone(); TiXmlNode* node = withThis.Clone();
if ( !node ) if ( !node )
return 0; return 0;
@ -317,6 +334,10 @@ TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& wit
bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
{ {
if ( !removeThis ) {
return false;
}
if ( removeThis->parent != this ) if ( removeThis->parent != this )
{ {
assert( 0 ); assert( 0 );
@ -502,7 +523,7 @@ const TiXmlDocument* TiXmlNode::GetDocument() const
TiXmlElement::TiXmlElement (const char * _value) TiXmlElement::TiXmlElement (const char * _value)
: TiXmlNode( TiXmlNode::ELEMENT ) : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{ {
firstChild = lastChild = 0; firstChild = lastChild = 0;
value = _value; value = _value;
@ -511,7 +532,7 @@ TiXmlElement::TiXmlElement (const char * _value)
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
TiXmlElement::TiXmlElement( const std::string& _value ) TiXmlElement::TiXmlElement( const std::string& _value )
: TiXmlNode( TiXmlNode::ELEMENT ) : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{ {
firstChild = lastChild = 0; firstChild = lastChild = 0;
value = _value; value = _value;
@ -520,17 +541,18 @@ TiXmlElement::TiXmlElement( const std::string& _value )
TiXmlElement::TiXmlElement( const TiXmlElement& copy) TiXmlElement::TiXmlElement( const TiXmlElement& copy)
: TiXmlNode( TiXmlNode::ELEMENT ) : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{ {
firstChild = lastChild = 0; firstChild = lastChild = 0;
copy.CopyTo( this ); copy.CopyTo( this );
} }
void TiXmlElement::operator=( const TiXmlElement& base ) TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base )
{ {
ClearThis(); ClearThis();
base.CopyTo( this ); base.CopyTo( this );
return *this;
} }
@ -564,9 +586,9 @@ const char* TiXmlElement::Attribute( const char* name ) const
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name ) const const std::string* TiXmlElement::Attribute( const std::string& name ) const
{ {
const TiXmlAttribute* node = attributeSet.Find( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( node ) if ( attrib )
return &node->ValueStr(); return &attrib->ValueStr();
return 0; return 0;
} }
#endif #endif
@ -574,195 +596,202 @@ const std::string* TiXmlElement::Attribute( const std::string& name ) const
const char* TiXmlElement::Attribute( const char* name, int* i ) const const char* TiXmlElement::Attribute( const char* name, int* i ) const
{ {
const char* s = Attribute( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( i ) const char* result = 0;
{
if ( s ) { if ( attrib ) {
*i = atoi( s ); result = attrib->Value();
} if ( i ) {
else { attrib->QueryIntValue( i );
*i = 0;
} }
} }
return s; return result;
} }
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
{ {
const std::string* s = Attribute( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( i ) const std::string* result = 0;
{
if ( s ) { if ( attrib ) {
*i = atoi( s->c_str() ); result = &attrib->ValueStr();
} if ( i ) {
else { attrib->QueryIntValue( i );
*i = 0;
} }
} }
return s; return result;
} }
#endif #endif
const char* TiXmlElement::Attribute( const char* name, double* d ) const const char* TiXmlElement::Attribute( const char* name, double* d ) const
{ {
const char* s = Attribute( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( d ) const char* result = 0;
{
if ( s ) { if ( attrib ) {
*d = atof( s ); result = attrib->Value();
} if ( d ) {
else { attrib->QueryDoubleValue( d );
*d = 0;
} }
} }
return s; return result;
} }
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
{ {
const std::string* s = Attribute( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( d ) const std::string* result = 0;
{
if ( s ) { if ( attrib ) {
*d = atof( s->c_str() ); result = &attrib->ValueStr();
} if ( d ) {
else { attrib->QueryDoubleValue( d );
*d = 0;
} }
} }
return s; return result;
} }
#endif #endif
int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !attrib )
return TIXML_NO_ATTRIBUTE;
return attrib->QueryIntValue( ival );
}
int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const
{ {
const TiXmlAttribute* node = attributeSet.Find( name ); const TiXmlAttribute* node = attributeSet.Find( name );
if ( !node ) if ( !node )
return TIXML_NO_ATTRIBUTE; return TIXML_NO_ATTRIBUTE;
return node->QueryIntValue( ival );
int ival = 0;
int result = node->QueryIntValue( &ival );
*value = (unsigned)ival;
return result;
} }
int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const
{
const TiXmlAttribute* node = attributeSet.Find( name );
if ( !node )
return TIXML_NO_ATTRIBUTE;
int result = TIXML_WRONG_TYPE;
if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) )
{
*bval = true;
result = TIXML_SUCCESS;
}
else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) )
{
*bval = false;
result = TIXML_SUCCESS;
}
return result;
}
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
{ {
const TiXmlAttribute* node = attributeSet.Find( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !node ) if ( !attrib )
return TIXML_NO_ATTRIBUTE; return TIXML_NO_ATTRIBUTE;
return node->QueryIntValue( ival ); return attrib->QueryIntValue( ival );
} }
#endif #endif
int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
{ {
const TiXmlAttribute* node = attributeSet.Find( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !node ) if ( !attrib )
return TIXML_NO_ATTRIBUTE; return TIXML_NO_ATTRIBUTE;
return node->QueryDoubleValue( dval ); return attrib->QueryDoubleValue( dval );
} }
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
{ {
const TiXmlAttribute* node = attributeSet.Find( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !node ) if ( !attrib )
return TIXML_NO_ATTRIBUTE; return TIXML_NO_ATTRIBUTE;
return node->QueryDoubleValue( dval ); return attrib->QueryDoubleValue( dval );
} }
#endif #endif
void TiXmlElement::SetAttribute( const char * name, int val ) void TiXmlElement::SetAttribute( const char * name, int val )
{ {
char buf[64]; TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
#if defined(TIXML_SNPRINTF) if ( attrib ) {
TIXML_SNPRINTF( buf, sizeof(buf), "%d", val ); attrib->SetIntValue( val );
#else }
sprintf( buf, "%d", val );
#endif
SetAttribute( name, buf );
} }
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& name, int val ) void TiXmlElement::SetAttribute( const std::string& name, int val )
{ {
std::ostringstream oss; TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
oss << val; if ( attrib ) {
SetAttribute( name, oss.str() ); attrib->SetIntValue( val );
}
} }
#endif #endif
void TiXmlElement::SetDoubleAttribute( const char * name, double val ) void TiXmlElement::SetDoubleAttribute( const char * name, double val )
{ {
char buf[256]; TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
#if defined(TIXML_SNPRINTF) if ( attrib ) {
TIXML_SNPRINTF( buf, sizeof(buf), "%f", val ); attrib->SetDoubleValue( val );
#else
sprintf( buf, "%f", val );
#endif
SetAttribute( name, buf );
}
void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
{
#ifdef TIXML_USE_STL
TIXML_STRING _name( cname );
TIXML_STRING _value( cvalue );
#else
const char* _name = cname;
const char* _value = cvalue;
#endif
TiXmlAttribute* node = attributeSet.Find( _name );
if ( node )
{
node->SetValue( _value );
return;
}
TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue );
if ( attrib )
{
attributeSet.Add( attrib );
}
else
{
TiXmlDocument* document = GetDocument();
if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
} }
} }
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value ) void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
{ {
TiXmlAttribute* node = attributeSet.Find( name ); TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( node ) if ( attrib ) {
{ attrib->SetDoubleValue( val );
node->SetValue( _value );
return;
} }
}
#endif
TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
if ( attrib ) void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
{ {
attributeSet.Add( attrib ); TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
if ( attrib ) {
attrib->SetValue( cvalue );
} }
else }
{
TiXmlDocument* document = GetDocument();
if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); #ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
if ( attrib ) {
attrib->SetValue( _value );
} }
} }
#endif #endif
@ -881,14 +910,14 @@ const char* TiXmlElement::GetText() const
} }
TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{ {
tabsize = 4; tabsize = 4;
useMicrosoftBOM = false; useMicrosoftBOM = false;
ClearError(); ClearError();
} }
TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{ {
tabsize = 4; tabsize = 4;
useMicrosoftBOM = false; useMicrosoftBOM = false;
@ -898,7 +927,7 @@ TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{ {
tabsize = 4; tabsize = 4;
useMicrosoftBOM = false; useMicrosoftBOM = false;
@ -908,49 +937,33 @@ TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiX
#endif #endif
TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{ {
copy.CopyTo( this ); copy.CopyTo( this );
} }
void TiXmlDocument::operator=( const TiXmlDocument& copy ) TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy )
{ {
Clear(); Clear();
copy.CopyTo( this ); copy.CopyTo( this );
return *this;
} }
bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
{ {
// See STL_STRING_BUG below.
//StringToBuffer buf( value );
return LoadFile( Value(), encoding ); return LoadFile( Value(), encoding );
} }
bool TiXmlDocument::SaveFile() const bool TiXmlDocument::SaveFile() const
{ {
// See STL_STRING_BUG below.
// StringToBuffer buf( value );
//
// if ( buf.buffer && SaveFile( buf.buffer ) )
// return true;
//
// return false;
return SaveFile( Value() ); return SaveFile( Value() );
} }
bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
{ {
// There was a really terrifying little bug here. The code:
// value = filename
// in the STL case, cause the assignment method of the std::string to
// be called. What is strange, is that the std::string had the same
// address as it's c_str() method, and so bad things happen. Looks
// like a bug in the Microsoft STL implementation.
// Add an extra string to avoid the crash.
TIXML_STRING filename( _filename ); TIXML_STRING filename( _filename );
value = filename; value = filename;
@ -995,11 +1008,6 @@ bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
return false; return false;
} }
// If we have a file, assume it is all one big XML file, and read it in.
// The document parser may decide the document ends sooner than the entire file, however.
TIXML_STRING data;
data.reserve( length );
// Subtle bug here. TinyXml did use fgets. But from the XML spec: // Subtle bug here. TinyXml did use fgets. But from the XML spec:
// 2.11 End-of-Line Handling // 2.11 End-of-Line Handling
// <snip> // <snip>
@ -1030,58 +1038,46 @@ bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
return false; return false;
} }
const char* lastPos = buf; // Process the buffer in place to normalize new lines. (See comment above.)
const char* p = buf; // Copies from the 'p' to 'q' pointer, where p can advance faster if
// a newline-carriage return is hit.
//
// Wikipedia:
// Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or
// CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
// * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
// * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
// * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9
const char* p = buf; // the read head
char* q = buf; // the write head
const char CR = 0x0d;
const char LF = 0x0a;
buf[length] = 0; buf[length] = 0;
while( *p ) { while( *p ) {
assert( p < (buf+length) ); assert( p < (buf+length) );
if ( *p == 0xa ) { assert( q <= (buf+length) );
// Newline character. No special rules for this. Append all the characters assert( q <= p );
// since the last string, and include the newline.
data.append( lastPos, (p-lastPos+1) ); // append, include the newline
++p; // move past the newline
lastPos = p; // and point to the new buffer (may be 0)
assert( p <= (buf+length) );
}
else if ( *p == 0xd ) {
// Carriage return. Append what we have so far, then
// handle moving forward in the buffer.
if ( (p-lastPos) > 0 ) {
data.append( lastPos, p-lastPos ); // do not add the CR
}
data += (char)0xa; // a proper newline
if ( *(p+1) == 0xa ) { if ( *p == CR ) {
// Carriage return - new line sequence *q++ = LF;
p += 2; p++;
lastPos = p; if ( *p == LF ) { // check for CR+LF (and skip LF)
assert( p <= (buf+length) ); p++;
}
else {
// it was followed by something else...that is presumably characters again.
++p;
lastPos = p;
assert( p <= (buf+length) );
} }
} }
else { else {
++p; *q++ = *p++;
} }
} }
// Handle any left over characters. assert( q <= (buf+length) );
if ( p-lastPos ) { *q = 0;
data.append( lastPos, p-lastPos );
} Parse( buf, 0, encoding );
delete [] buf; delete [] buf;
buf = 0; return !Error();
Parse( data.c_str(), 0, encoding );
if ( Error() )
return false;
else
return true;
} }
@ -1220,7 +1216,7 @@ void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) cons
if (value.find ('\"') == TIXML_STRING::npos) { if (value.find ('\"') == TIXML_STRING::npos) {
if ( cfile ) { if ( cfile ) {
fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
} }
if ( str ) { if ( str ) {
(*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
@ -1228,7 +1224,7 @@ void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) cons
} }
else { else {
if ( cfile ) { if ( cfile ) {
fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
} }
if ( str ) { if ( str ) {
(*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
@ -1266,9 +1262,9 @@ void TiXmlAttribute::SetDoubleValue( double _value )
{ {
char buf [256]; char buf [256];
#if defined(TIXML_SNPRINTF) #if defined(TIXML_SNPRINTF)
TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value); TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
#else #else
sprintf (buf, "%lf", _value); sprintf (buf, "%g", _value);
#endif #endif
SetValue (buf); SetValue (buf);
} }
@ -1284,16 +1280,17 @@ double TiXmlAttribute::DoubleValue() const
} }
TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
{ {
copy.CopyTo( this ); copy.CopyTo( this );
} }
void TiXmlComment::operator=( const TiXmlComment& base ) TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base )
{ {
Clear(); Clear();
base.CopyTo( this ); base.CopyTo( this );
return *this;
} }
@ -1382,7 +1379,7 @@ TiXmlNode* TiXmlText::Clone() const
TiXmlDeclaration::TiXmlDeclaration( const char * _version, TiXmlDeclaration::TiXmlDeclaration( const char * _version,
const char * _encoding, const char * _encoding,
const char * _standalone ) const char * _standalone )
: TiXmlNode( TiXmlNode::DECLARATION ) : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{ {
version = _version; version = _version;
encoding = _encoding; encoding = _encoding;
@ -1394,7 +1391,7 @@ TiXmlDeclaration::TiXmlDeclaration( const char * _version,
TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
const std::string& _encoding, const std::string& _encoding,
const std::string& _standalone ) const std::string& _standalone )
: TiXmlNode( TiXmlNode::DECLARATION ) : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{ {
version = _version; version = _version;
encoding = _encoding; encoding = _encoding;
@ -1404,16 +1401,17 @@ TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
: TiXmlNode( TiXmlNode::DECLARATION ) : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{ {
copy.CopyTo( this ); copy.CopyTo( this );
} }
void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
{ {
Clear(); Clear();
copy.CopyTo( this ); copy.CopyTo( this );
return *this;
} }
@ -1548,18 +1546,7 @@ void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
{
for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
{
if ( node->name == name )
return node;
}
return 0;
}
/*
TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name )
{ {
for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
{ {
@ -1568,22 +1555,21 @@ TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name )
} }
return 0; return 0;
} }
*/
TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
{
TiXmlAttribute* attrib = Find( _name );
if ( !attrib ) {
attrib = new TiXmlAttribute();
Add( attrib );
attrib->SetName( _name );
}
return attrib;
}
#endif #endif
const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
{
for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
{
if ( strcmp( node->name.c_str(), name ) == 0 )
return node;
}
return 0;
}
/*
TiXmlAttribute* TiXmlAttributeSet::Find( const char* name )
{ {
for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
{ {
@ -1592,7 +1578,19 @@ TiXmlAttribute* TiXmlAttributeSet::Find( const char* name )
} }
return 0; return 0;
} }
*/
TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
{
TiXmlAttribute* attrib = Find( _name );
if ( !attrib ) {
attrib = new TiXmlAttribute();
Add( attrib );
attrib->SetName( _name );
}
return attrib;
}
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
std::istream& operator>> (std::istream & in, TiXmlNode & base) std::istream& operator>> (std::istream & in, TiXmlNode & base)

View File

@ -1,6 +1,6 @@
/* /*
www.sourceforge.net/projects/tinyxml www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) Original code by Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any warranty. In no event will the authors be held liable for any
@ -63,21 +63,19 @@ distribution.
#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
// Microsoft visual studio, version 2005 and higher. // Microsoft visual studio, version 2005 and higher.
#define TIXML_SNPRINTF _snprintf_s #define TIXML_SNPRINTF _snprintf_s
#define TIXML_SNSCANF _snscanf_s
#define TIXML_SSCANF sscanf_s #define TIXML_SSCANF sscanf_s
#elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
// Microsoft visual studio, version 6 and higher. // Microsoft visual studio, version 6 and higher.
//#pragma message( "Using _sn* functions." ) //#pragma message( "Using _sn* functions." )
#define TIXML_SNPRINTF _snprintf #define TIXML_SNPRINTF _snprintf
#define TIXML_SNSCANF _snscanf
#define TIXML_SSCANF sscanf #define TIXML_SSCANF sscanf
#elif defined(__GNUC__) && (__GNUC__ >= 3 ) #elif defined(__GNUC__) && (__GNUC__ >= 3 )
// GCC version 3 and higher.s // GCC version 3 and higher.s
//#warning( "Using sn* functions." ) //#warning( "Using sn* functions." )
#define TIXML_SNPRINTF snprintf #define TIXML_SNPRINTF snprintf
#define TIXML_SNSCANF snscanf
#define TIXML_SSCANF sscanf #define TIXML_SSCANF sscanf
#else #else
#define TIXML_SNPRINTF snprintf
#define TIXML_SSCANF sscanf #define TIXML_SSCANF sscanf
#endif #endif
#endif #endif
@ -92,8 +90,8 @@ class TiXmlDeclaration;
class TiXmlParsingData; class TiXmlParsingData;
const int TIXML_MAJOR_VERSION = 2; const int TIXML_MAJOR_VERSION = 2;
const int TIXML_MINOR_VERSION = 5; const int TIXML_MINOR_VERSION = 6;
const int TIXML_PATCH_VERSION = 3; const int TIXML_PATCH_VERSION = 2;
/* Internal structure for tracking location of items /* Internal structure for tracking location of items
in the XML file. in the XML file.
@ -109,10 +107,11 @@ struct TiXmlCursor
/** /**
Implements the interface to the "Visitor pattern" (see the Accept() method.)
If you call the Accept() method, it requires being passed a TiXmlVisitor If you call the Accept() method, it requires being passed a TiXmlVisitor
class to handle callbacks. For nodes that contain other nodes (Document, Element) 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 you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
are simple called with Visit(). are simply called with Visit().
If you return 'true' from a Visit method, recursive parsing will continue. If you return 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. false, <b>no children of this node or its sibilings</b> will be Visited.
@ -147,7 +146,7 @@ public:
virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } virtual bool Visit( const TiXmlText& /*text*/ ) { return true; }
/// Visit a comment node /// Visit a comment node
virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; }
/// Visit an unknow node /// Visit an unknown node
virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; }
}; };
@ -267,7 +266,6 @@ public:
TIXML_NO_ERROR = 0, TIXML_NO_ERROR = 0,
TIXML_ERROR, TIXML_ERROR,
TIXML_ERROR_OPENING_FILE, TIXML_ERROR_OPENING_FILE,
TIXML_ERROR_OUT_OF_MEMORY,
TIXML_ERROR_PARSING_ELEMENT, TIXML_ERROR_PARSING_ELEMENT,
TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
TIXML_ERROR_READING_ELEMENT_VALUE, TIXML_ERROR_READING_ELEMENT_VALUE,
@ -288,6 +286,7 @@ public:
protected: protected:
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' ); return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
@ -462,13 +461,13 @@ public:
*/ */
enum NodeType enum NodeType
{ {
DOCUMENT, TINYXML_DOCUMENT,
ELEMENT, TINYXML_ELEMENT,
COMMENT, TINYXML_COMMENT,
UNKNOWN, TINYXML_UNKNOWN,
TEXT, TINYXML_TEXT,
DECLARATION, TINYXML_DECLARATION,
TYPECOUNT TINYXML_TYPECOUNT
}; };
virtual ~TiXmlNode(); virtual ~TiXmlNode();
@ -679,8 +678,8 @@ public:
#endif #endif
/** Query the type (as an enumerated value, above) of this node. /** Query the type (as an enumerated value, above) of this node.
The possible types are: DOCUMENT, ELEMENT, COMMENT, The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT,
UNKNOWN, TEXT, and DECLARATION. TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION.
*/ */
int Type() const { return type; } int Type() const { return type; }
@ -915,17 +914,14 @@ public:
const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
TiXmlAttribute* Last() { 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 ) const;
TiXmlAttribute* Find( const char* _name ) { TiXmlAttribute* FindOrCreate( const char* _name );
return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
} # ifdef TIXML_USE_STL
#ifdef TIXML_USE_STL TiXmlAttribute* Find( const std::string& _name ) const;
const TiXmlAttribute* Find( const std::string& _name ) const; TiXmlAttribute* FindOrCreate( const std::string& _name );
TiXmlAttribute* Find( const std::string& _name ) { # endif
return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
}
#endif
private: private:
//*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
@ -954,7 +950,7 @@ public:
TiXmlElement( const TiXmlElement& ); TiXmlElement( const TiXmlElement& );
void operator=( const TiXmlElement& base ); TiXmlElement& operator=( const TiXmlElement& base );
virtual ~TiXmlElement(); virtual ~TiXmlElement();
@ -987,6 +983,13 @@ public:
does not exist, then TIXML_NO_ATTRIBUTE is returned. does not exist, then TIXML_NO_ATTRIBUTE is returned.
*/ */
int QueryIntAttribute( const char* name, int* _value ) const; 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(). /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
int QueryDoubleAttribute( const char* name, double* _value ) const; int QueryDoubleAttribute( const char* name, double* _value ) const;
/// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
@ -1000,11 +1003,21 @@ public:
} }
#ifdef TIXML_USE_STL #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 /** Template form of the attribute query which will try to read the
attribute into the specified type. Very easy, very powerful, but attribute into the specified type. Very easy, very powerful, but
be careful to make sure to call this with the correct type. be careful to make sure to call this with the correct type.
NOTE: This method doesn't work correctly for 'string' types. NOTE: This method doesn't work correctly for 'string' types that contain spaces.
@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
*/ */
@ -1020,13 +1033,8 @@ public:
return TIXML_SUCCESS; return TIXML_SUCCESS;
return TIXML_WRONG_TYPE; return TIXML_WRONG_TYPE;
} }
/*
This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string" int QueryValueAttribute( const std::string& name, std::string* outValue ) const
but template specialization is hard to get working cross-compiler. Leaving the bug for now.
// The above will fail for std::string because the space character is used as a seperator.
// Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string
template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const
{ {
const TiXmlAttribute* node = attributeSet.Find( name ); const TiXmlAttribute* node = attributeSet.Find( name );
if ( !node ) if ( !node )
@ -1034,7 +1042,6 @@ public:
*outValue = node->ValueStr(); *outValue = node->ValueStr();
return TIXML_SUCCESS; return TIXML_SUCCESS;
} }
*/
#endif #endif
/** Sets an attribute of name to a given value. The attribute /** Sets an attribute of name to a given value. The attribute
@ -1053,6 +1060,8 @@ public:
void SetAttribute( const std::string& name, const std::string& _value ); void SetAttribute( const std::string& name, const std::string& _value );
///< STL std::string form. ///< STL std::string form.
void SetAttribute( const std::string& name, int _value ); void SetAttribute( const std::string& name, int _value );
///< STL std::string form.
void SetDoubleAttribute( const std::string& name, double value );
#endif #endif
/** Sets an attribute of name to a given value. The attribute /** Sets an attribute of name to a given value. The attribute
@ -1144,7 +1153,6 @@ protected:
const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
private: private:
TiXmlAttributeSet attributeSet; TiXmlAttributeSet attributeSet;
}; };
@ -1155,13 +1163,13 @@ class TiXmlComment : public TiXmlNode
{ {
public: public:
/// Constructs an empty comment. /// Constructs an empty comment.
TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
/// Construct a comment from text. /// Construct a comment from text.
TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
SetValue( _value ); SetValue( _value );
} }
TiXmlComment( const TiXmlComment& ); TiXmlComment( const TiXmlComment& );
void operator=( const TiXmlComment& base ); TiXmlComment& operator=( const TiXmlComment& base );
virtual ~TiXmlComment() {} virtual ~TiXmlComment() {}
@ -1175,8 +1183,8 @@ public:
*/ */
virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 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 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. 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. /** Walk the XML tree visiting this node and all of its children.
*/ */
@ -1209,7 +1217,7 @@ public:
normal, encoded text. If you want it be output as a CDATA text normal, encoded text. If you want it be output as a CDATA text
element, set the parameter _cdata to 'true' element, set the parameter _cdata to 'true'
*/ */
TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
{ {
SetValue( initValue ); SetValue( initValue );
cdata = false; cdata = false;
@ -1218,15 +1226,15 @@ public:
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
/// Constructor. /// Constructor.
TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
{ {
SetValue( initValue ); SetValue( initValue );
cdata = false; cdata = false;
} }
#endif #endif
TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); }
void operator=( const TiXmlText& base ) { base.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; virtual void Print( FILE* cfile, int depth ) const;
@ -1278,7 +1286,7 @@ class TiXmlDeclaration : public TiXmlNode
{ {
public: public:
/// Construct an empty declaration. /// Construct an empty declaration.
TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
/// Constructor. /// Constructor.
@ -1293,7 +1301,7 @@ public:
const char* _standalone ); const char* _standalone );
TiXmlDeclaration( const TiXmlDeclaration& copy ); TiXmlDeclaration( const TiXmlDeclaration& copy );
void operator=( const TiXmlDeclaration& copy ); TiXmlDeclaration& operator=( const TiXmlDeclaration& copy );
virtual ~TiXmlDeclaration() {} virtual ~TiXmlDeclaration() {}
@ -1346,11 +1354,11 @@ private:
class TiXmlUnknown : public TiXmlNode class TiXmlUnknown : public TiXmlNode
{ {
public: public:
TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {}
virtual ~TiXmlUnknown() {} virtual ~TiXmlUnknown() {}
TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); }
void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } TiXmlUnknown& operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); return *this; }
/// Creates a copy of this Unknown and returns it. /// Creates a copy of this Unknown and returns it.
virtual TiXmlNode* Clone() const; virtual TiXmlNode* Clone() const;
@ -1359,8 +1367,8 @@ public:
virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 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 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. 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. /** Walk the XML tree visiting this node and all of its children.
*/ */
@ -1396,7 +1404,7 @@ public:
#endif #endif
TiXmlDocument( const TiXmlDocument& copy ); TiXmlDocument( const TiXmlDocument& copy );
void operator=( const TiXmlDocument& copy ); TiXmlDocument& operator=( const TiXmlDocument& copy );
virtual ~TiXmlDocument() {} virtual ~TiXmlDocument() {}
@ -1423,14 +1431,10 @@ public:
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. 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 ); return LoadFile( filename.c_str(), encoding );
} }
bool SaveFile( const std::string& filename ) const ///< STL std::string version. 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() ); return SaveFile( filename.c_str() );
} }
#endif #endif
@ -1638,7 +1642,7 @@ public:
TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } TiXmlHandle( TiXmlNode* _node ) { this->node = _node; }
/// Copy constructor /// Copy constructor
TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } 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. /// Return a handle to the first child node.
TiXmlHandle FirstChild() const; TiXmlHandle FirstChild() const;
@ -1799,4 +1803,3 @@ private:
#endif #endif
#endif #endif

View File

@ -31,12 +31,11 @@ distribution.
// It also cleans up the code a bit. // It also cleans up the code a bit.
// //
const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] =
{ {
"No error", "No error",
"Error", "Error",
"Failed to open file", "Failed to open file",
"Memory allocation failed.",
"Error parsing Element.", "Error parsing Element.",
"Failed to read Element name", "Failed to read Element name",
"Error reading Element value.", "Error reading Element value.",

View File

@ -1,6 +1,6 @@
/* /*
www.sourceforge.net/projects/tinyxml 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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any warranty. In no event will the authors be held liable for any
@ -40,7 +40,7 @@ distribution.
// Note tha "PutString" hardcodes the same list. This // Note tha "PutString" hardcodes the same list. This
// is less flexible than it appears. Changing the entries // is less flexible than it appears. Changing the entries
// or order will break putstring. // or order will break putstring.
TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] =
{ {
{ "&amp;", 5, '&' }, { "&amp;", 5, '&' },
{ "&lt;", 4, '<' }, { "&lt;", 4, '<' },
@ -174,7 +174,7 @@ class TiXmlParsingData
public: public:
void Stamp( const char* now, TiXmlEncoding encoding ); void Stamp( const char* now, TiXmlEncoding encoding );
const TiXmlCursor& Cursor() { return cursor; } const TiXmlCursor& Cursor() const { return cursor; }
private: private:
// Only used by the document! // Only used by the document!
@ -346,7 +346,7 @@ const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
continue; continue;
} }
if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. if ( IsWhiteSpace( *p ) ) // Still using old rules for white space.
++p; ++p;
else else
break; break;
@ -354,7 +354,7 @@ const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
} }
else else
{ {
while ( (*p && IsWhiteSpace( *p )) || *p == '\n' || *p =='\r' ) while ( *p && IsWhiteSpace( *p ) )
++p; ++p;
} }
@ -631,9 +631,9 @@ const char* TiXmlBase::ReadText( const char* p,
} }
} }
} }
if ( p ) if ( p && *p )
p += strlen( endTag ); p += strlen( endTag );
return p; return ( p && *p ) ? p : 0;
} }
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
@ -825,7 +825,6 @@ TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
return 0; return 0;
} }
TiXmlDocument* doc = GetDocument();
p = SkipWhiteSpace( p, encoding ); p = SkipWhiteSpace( p, encoding );
if ( !p || !*p ) if ( !p || !*p )
@ -896,11 +895,6 @@ TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
// Set the parent, so it can report errors // Set the parent, so it can report errors
returnNode->parent = this; returnNode->parent = this;
} }
else
{
if ( doc )
doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
}
return returnNode; return returnNode;
} }
@ -1083,7 +1077,6 @@ const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
TIXML_STRING endTag ("</"); TIXML_STRING endTag ("</");
endTag += value; endTag += value;
endTag += ">";
// Check for and read attributes. Also look for an empty // Check for and read attributes. Also look for an empty
// tag or an end tag. // tag or an end tag.
@ -1122,10 +1115,20 @@ const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
} }
// We should find the end tag now // We should find the end tag now
// note that:
// </foo > and
// </foo>
// are both valid end tags.
if ( StringEqual( p, endTag.c_str(), false, encoding ) ) if ( StringEqual( p, endTag.c_str(), false, encoding ) )
{ {
p += endTag.length(); p += endTag.length();
return p; p = SkipWhiteSpace( p, encoding );
if ( p && *p && *p == '>' ) {
++p;
return p;
}
if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
return 0;
} }
else else
{ {
@ -1139,7 +1142,6 @@ const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
TiXmlAttribute* attrib = new TiXmlAttribute(); TiXmlAttribute* attrib = new TiXmlAttribute();
if ( !attrib ) if ( !attrib )
{ {
if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
return 0; return 0;
} }
@ -1162,7 +1164,7 @@ const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
#endif #endif
if ( node ) if ( node )
{ {
node->SetValue( attrib->Value() ); if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
delete attrib; delete attrib;
return 0; return 0;
} }
@ -1191,8 +1193,7 @@ const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXm
if ( !textNode ) if ( !textNode )
{ {
if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding ); return 0;
return 0;
} }
if ( TiXmlBase::IsWhiteSpaceCondensed() ) if ( TiXmlBase::IsWhiteSpaceCondensed() )
@ -1297,9 +1298,10 @@ const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
if ( !p ) if ( !p )
{ {
if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding ); if ( document )
document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
} }
if ( *p == '>' ) if ( p && *p == '>' )
return p+1; return p+1;
return p; return p;
} }
@ -1349,7 +1351,8 @@ const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
if ( !StringEqual( p, startTag, false, encoding ) ) if ( !StringEqual( p, startTag, false, encoding ) )
{ {
document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); if ( document )
document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
return 0; return 0;
} }
p += strlen( startTag ); p += strlen( startTag );
@ -1379,7 +1382,7 @@ const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
value.append( p, 1 ); value.append( p, 1 );
++p; ++p;
} }
if ( p ) if ( p && *p )
p += strlen( endTag ); p += strlen( endTag );
return p; return p;
@ -1391,10 +1394,6 @@ const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlE
p = SkipWhiteSpace( p, encoding ); p = SkipWhiteSpace( p, encoding );
if ( !p || !*p ) return 0; if ( !p || !*p ) return 0;
// int tabsize = 4;
// if ( document )
// tabsize = document->TabSize();
if ( data ) if ( data )
{ {
data->Stamp( p, encoding ); data->Stamp( p, encoding );
@ -1446,7 +1445,7 @@ const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlE
// its best, even without them. // its best, even without them.
value = ""; value = "";
while ( p && *p // existence while ( p && *p // existence
&& !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace && !IsWhiteSpace( *p ) // whitespace
&& *p != '/' && *p != '>' ) // tag end && *p != '/' && *p != '>' ) // tag end
{ {
if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
@ -1515,7 +1514,8 @@ const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncodi
if ( !StringEqual( p, startTag, false, encoding ) ) if ( !StringEqual( p, startTag, false, encoding ) )
{ {
document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); if ( document )
document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
return 0; return 0;
} }
p += strlen( startTag ); p += strlen( startTag );
@ -1539,7 +1539,7 @@ const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncodi
const char* end = "<"; const char* end = "<";
p = ReadText( p, &value, ignoreWhite, end, false, encoding ); p = ReadText( p, &value, ignoreWhite, end, false, encoding );
if ( p ) if ( p && *p )
return p-1; // don't truncate the '<' return p-1; // don't truncate the '<'
return 0; return 0;
} }

View File

@ -19,11 +19,15 @@
#include "tinyxml.h" #include "tinyxml.h"
bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho = false);
bool XmlTest( const char* testString, int expected, int found, bool noEcho = false );
static int gPass = 0; static int gPass = 0;
static int gFail = 0; static int gFail = 0;
bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho = false)
bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho )
{ {
bool pass = !strcmp( expected, found ); bool pass = !strcmp( expected, found );
if ( pass ) if ( pass )
@ -44,7 +48,7 @@ bool XmlTest (const char* testString, const char* expected, const char* found, b
} }
bool XmlTest( const char* testString, int expected, int found, bool noEcho = false ) bool XmlTest( const char* testString, int expected, int found, bool noEcho )
{ {
bool pass = ( expected == found ); bool pass = ( expected == found );
if ( pass ) if ( pass )
@ -65,6 +69,17 @@ bool XmlTest( const char* testString, int expected, int found, bool noEcho = fal
} }
void NullLineEndings( char* p )
{
while( p && *p ) {
if ( *p == '\n' || *p == '\r' ) {
*p = 0;
return;
}
++p;
}
}
// //
// This file demonstrates some basic functionality of TinyXml. // This file demonstrates some basic functionality of TinyXml.
// Note that the example is very contrived. It presumes you know // Note that the example is very contrived. It presumes you know
@ -74,6 +89,7 @@ bool XmlTest( const char* testString, int expected, int found, bool noEcho = fal
int main() int main()
{ {
// //
// We start with the 'demoStart' todo list. Process it. And // We start with the 'demoStart' todo list. Process it. And
// should hopefully end up with the todo list as illustrated. // should hopefully end up with the todo list as illustrated.
@ -91,8 +107,8 @@ int main()
{ {
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
/* What the todo list should look like after processing. // What the todo list should look like after processing.
In stream (no formatting) representation. */ // In stream (no formatting) representation.
const char* demoEnd = const char* demoEnd =
"<?xml version=\"1.0\" standalone=\"no\" ?>" "<?xml version=\"1.0\" standalone=\"no\" ?>"
"<!-- Our to do list data -->" "<!-- Our to do list data -->"
@ -399,7 +415,7 @@ int main()
} }
#endif #endif
} }
{ {
const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />"; const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
@ -424,6 +440,30 @@ int main()
result = ele->QueryIntAttribute( "bar", &iVal ); result = ele->QueryIntAttribute( "bar", &iVal );
XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE ); XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE );
} }
{
const char* str = "<doc/>";
TiXmlDocument doc;
doc.Parse( str );
TiXmlElement* ele = doc.FirstChildElement();
int iVal;
double dVal;
ele->SetAttribute( "str", "strValue" );
ele->SetAttribute( "int", 1 );
ele->SetDoubleAttribute( "double", -1.0 );
const char* cStr = ele->Attribute( "str" );
ele->QueryIntAttribute( "int", &iVal );
ele->QueryDoubleAttribute( "double", &dVal );
XmlTest( "Attribute round trip. c-string.", "strValue", cStr );
XmlTest( "Attribute round trip. int.", 1, iVal );
XmlTest( "Attribute round trip. double.", -1, (int)dVal );
}
{ {
const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n" const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
@ -558,20 +598,30 @@ int main()
FILE* saved = fopen( "utf8testout.xml", "r" ); FILE* saved = fopen( "utf8testout.xml", "r" );
FILE* verify = fopen( "utf8testverify.xml", "r" ); FILE* verify = fopen( "utf8testverify.xml", "r" );
//bool firstLineBOM=true;
if ( saved && verify ) if ( saved && verify )
{ {
while ( fgets( verifyBuf, 256, verify ) ) while ( fgets( verifyBuf, 256, verify ) )
{ {
fgets( savedBuf, 256, saved ); fgets( savedBuf, 256, saved );
if ( strcmp( verifyBuf, savedBuf ) ) NullLineEndings( verifyBuf );
NullLineEndings( savedBuf );
if ( /*!firstLineBOM && */ strcmp( verifyBuf, savedBuf ) )
{ {
printf( "verify:%s<\n", verifyBuf );
printf( "saved :%s<\n", savedBuf );
okay = 0; okay = 0;
break; break;
} }
//firstLineBOM = false;
} }
fclose( saved );
fclose( verify );
} }
if ( saved )
fclose( saved );
if ( verify )
fclose( verify );
XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay ); XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay );
// On most Western machines, this is an element that contains // On most Western machines, this is an element that contains
@ -1063,8 +1113,8 @@ int main()
TiXmlDocument doc; TiXmlDocument doc;
doc.Parse( doctype ); doc.Parse( doctype );
XmlTest( "Parsing repeated attributes.", 0, (int)doc.Error() ); // not an error to tinyxml XmlTest( "Parsing repeated attributes.", true, doc.Error() ); // is an error to tinyxml (didn't use to be, but caused issues)
XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) ); //XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) );
} }
{ {
@ -1161,19 +1211,19 @@ int main()
int i; int i;
float f; float f;
bool b; bool b;
//std::string str; std::string str;
XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &d ), TIXML_SUCCESS ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &d ), TIXML_SUCCESS );
XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &i ), TIXML_SUCCESS ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &i ), TIXML_SUCCESS );
XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &f ), TIXML_SUCCESS ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &f ), TIXML_SUCCESS );
XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &b ), TIXML_WRONG_TYPE ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &b ), TIXML_WRONG_TYPE );
XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "nobar", &b ), TIXML_NO_ATTRIBUTE ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "nobar", &b ), TIXML_NO_ATTRIBUTE );
//XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "barStr", &str ), TIXML_SUCCESS ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "barStr", &str ), TIXML_SUCCESS );
XmlTest( "QueryValueAttribute", (d==3.0), true ); XmlTest( "QueryValueAttribute", (d==3.0), true );
XmlTest( "QueryValueAttribute", (i==3), true ); XmlTest( "QueryValueAttribute", (i==3), true );
XmlTest( "QueryValueAttribute", (f==3.0f), true ); XmlTest( "QueryValueAttribute", (f==3.0f), true );
//XmlTest( "QueryValueAttribute", (str==std::string( "a string" )), true ); XmlTest( "QueryValueAttribute", (str==std::string( "a string" )), true );
} }
#endif #endif
@ -1256,16 +1306,66 @@ int main()
XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true ); XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
XmlTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true ); XmlTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
} }
/*
{ {
TiXmlDocument xml; TiXmlDocument xml;
xml.Parse( "<tag>/</tag>" ); xml.Parse( "<Parent>"
xml.Print(); "<child1 att=''/>"
xml.FirstChild()->Print( stdout, 0 ); "<!-- With this comment, child2 will not be parsed! -->"
xml.FirstChild()->Type(); "<child2 att=''/>"
"</Parent>" );
int count = 0;
TiXmlNode* ele = 0;
while ( (ele = xml.FirstChildElement( "Parent" )->IterateChildren( ele ) ) != 0 ) {
++count;
}
XmlTest( "Comments iterate correctly.", 3, count );
} }
*/
{
// trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well.
unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl";
buf[60] = 239;
buf[61] = 0;
TiXmlDocument doc;
doc.Parse( (const char*)buf);
}
{
// bug 1827248 Error while parsing a little bit malformed file
// Actually not malformed - should work.
TiXmlDocument xml;
xml.Parse( "<attributelist> </attributelist >" );
XmlTest( "Handle end tag whitespace", false, xml.Error() );
}
{
// This one must not result in an infinite loop
TiXmlDocument xml;
xml.Parse( "<infinite>loop" );
XmlTest( "Infinite loop test.", true, true );
}
{
// 1709904 - can not repro the crash
{
TiXmlDocument xml;
xml.Parse( "<tag>/</tag>" );
XmlTest( "Odd XML parsing.", xml.FirstChild()->Value(), "tag" );
}
/* Could not repro. {
TiXmlDocument xml;
xml.LoadFile( "EQUI_Inventory.xml" );
//XmlTest( "Odd XML parsing.", xml.FirstChildElement()->Value(), "XML" );
TiXmlPrinter printer;
xml.Accept( &printer );
fprintf( stdout, "%s", printer.CStr() );
}*/
}
/* 1417717 experiment /* 1417717 experiment
{ {
TiXmlDocument xml; TiXmlDocument xml;
@ -1278,6 +1378,7 @@ int main()
xml.Print(stdout); xml.Print(stdout);
} }
*/ */
#if defined( WIN32 ) && defined( TUNE ) #if defined( WIN32 ) && defined( TUNE )
_CrtMemCheckpoint( &endMemState ); _CrtMemCheckpoint( &endMemState );
//_CrtMemDumpStatistics( &endMemState ); //_CrtMemDumpStatistics( &endMemState );
@ -1290,5 +1391,3 @@ int main()
printf ("\nPass %d, Fail %d\n", gPass, gFail); printf ("\nPass %d, Fail %d\n", gPass, gFail);
return gFail; return gFail;
} }

View File

@ -687,11 +687,11 @@ void DataTree::setFromXML(DataNode *elem, TiXmlNode *elxml, bool root_node, DT_F
string tmp_str; string tmp_str;
switch (t) { switch (t) {
case TiXmlNode::DOCUMENT: case TiXmlNode::TINYXML_DOCUMENT:
// printf( "Document" ); // printf( "Document" );
break; break;
case TiXmlNode::ELEMENT: case TiXmlNode::TINYXML_ELEMENT:
if (!root_node) if (!root_node)
elem = elem->newChild(elxml->Value()); elem = elem->newChild(elxml->Value());
@ -712,15 +712,15 @@ void DataTree::setFromXML(DataNode *elem, TiXmlNode *elxml, bool root_node, DT_F
// printf( "Element \"%s\"", elxml->Value()); // printf( "Element \"%s\"", elxml->Value());
break; break;
case TiXmlNode::COMMENT: case TiXmlNode::TINYXML_COMMENT:
// printf( "Comment: \"%s\"", elxml->Value()); // printf( "Comment: \"%s\"", elxml->Value());
break; break;
case TiXmlNode::UNKNOWN: case TiXmlNode::TINYXML_UNKNOWN:
// printf( "Unknown" ); // printf( "Unknown" );
break; break;
case TiXmlNode::TEXT: case TiXmlNode::TINYXML_TEXT:
pText = elxml->ToText(); pText = elxml->ToText();
decodeXMLText(elem, pText->Value(), fpp); decodeXMLText(elem, pText->Value(), fpp);
@ -729,7 +729,7 @@ void DataTree::setFromXML(DataNode *elem, TiXmlNode *elxml, bool root_node, DT_F
// printf( "Text: [%s]", pText->Value() ); // printf( "Text: [%s]", pText->Value() );
break; break;
case TiXmlNode::DECLARATION: case TiXmlNode::TINYXML_DECLARATION:
// printf( "Declaration" ); // printf( "Declaration" );
break; break;
default: default:
@ -741,7 +741,7 @@ void DataTree::setFromXML(DataNode *elem, TiXmlNode *elxml, bool root_node, DT_F
TiXmlNode * pChild; TiXmlNode * pChild;
if (!elxml->NoChildren()) { if (!elxml->NoChildren()) {
if (elxml->FirstChild()->Type() == TiXmlNode::ELEMENT) { if (elxml->FirstChild()->Type() == TiXmlNode::TINYXML_ELEMENT) {
if (elxml->FirstChild()->Value() == TIXML_STRING("str")) { if (elxml->FirstChild()->Value() == TIXML_STRING("str")) {
std::vector<std::string> tmp_strvect; std::vector<std::string> tmp_strvect;