parent
cc7f69da54
commit
1da9005861
|
@ -24,7 +24,7 @@ distribution.
|
|||
#include "tinyxml2.h"
|
||||
|
||||
#include <new> // yes, this one new style header, is in the Android SDK.
|
||||
# ifdef ANDROID_NDK
|
||||
#if defined(ANDROID_NDK) || defined(__QNXNTO__)
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# include <cstddef>
|
||||
|
@ -70,6 +70,29 @@ StrPair::~StrPair()
|
|||
}
|
||||
|
||||
|
||||
void StrPair::TransferTo( StrPair* other )
|
||||
{
|
||||
if ( this == other ) {
|
||||
return;
|
||||
}
|
||||
// This in effect implements the assignment operator by "moving"
|
||||
// ownership (as in auto_ptr).
|
||||
|
||||
TIXMLASSERT( other->_flags == 0 );
|
||||
TIXMLASSERT( other->_start == 0 );
|
||||
TIXMLASSERT( other->_end == 0 );
|
||||
|
||||
other->Reset();
|
||||
|
||||
other->_flags = _flags;
|
||||
other->_start = _start;
|
||||
other->_end = _end;
|
||||
|
||||
_flags = 0;
|
||||
_start = 0;
|
||||
_end = 0;
|
||||
}
|
||||
|
||||
void StrPair::Reset()
|
||||
{
|
||||
if ( _flags & NEEDS_DELETE ) {
|
||||
|
@ -511,16 +534,19 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
|||
#endif
|
||||
XMLNode* returnNode = 0;
|
||||
if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() );
|
||||
returnNode = new (_commentPool.Alloc()) XMLDeclaration( this );
|
||||
returnNode->_memPool = &_commentPool;
|
||||
p += xmlHeaderLen;
|
||||
}
|
||||
else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLComment ) == _commentPool.ItemSize() );
|
||||
returnNode = new (_commentPool.Alloc()) XMLComment( this );
|
||||
returnNode->_memPool = &_commentPool;
|
||||
p += commentHeaderLen;
|
||||
}
|
||||
else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );
|
||||
XMLText* text = new (_textPool.Alloc()) XMLText( this );
|
||||
returnNode = text;
|
||||
returnNode->_memPool = &_textPool;
|
||||
|
@ -528,16 +554,19 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
|||
text->SetCData( true );
|
||||
}
|
||||
else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLUnknown ) == _commentPool.ItemSize() );
|
||||
returnNode = new (_commentPool.Alloc()) XMLUnknown( this );
|
||||
returnNode->_memPool = &_commentPool;
|
||||
p += dtdHeaderLen;
|
||||
}
|
||||
else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) {
|
||||
TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() );
|
||||
returnNode = new (_elementPool.Alloc()) XMLElement( this );
|
||||
returnNode->_memPool = &_elementPool;
|
||||
p += elementHeaderLen;
|
||||
}
|
||||
else {
|
||||
TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );
|
||||
returnNode = new (_textPool.Alloc()) XMLText( this );
|
||||
returnNode->_memPool = &_textPool;
|
||||
p = start; // Back it up, all the text counts.
|
||||
|
@ -600,6 +629,7 @@ void XMLNode::SetValue( const char* str, bool staticMem )
|
|||
void XMLNode::DeleteChildren()
|
||||
{
|
||||
while( _firstChild ) {
|
||||
TIXMLASSERT( _firstChild->_document == _document );
|
||||
XMLNode* node = _firstChild;
|
||||
Unlink( node );
|
||||
|
||||
|
@ -611,6 +641,7 @@ void XMLNode::DeleteChildren()
|
|||
|
||||
void XMLNode::Unlink( XMLNode* child )
|
||||
{
|
||||
TIXMLASSERT( child->_document == _document );
|
||||
if ( child == _firstChild ) {
|
||||
_firstChild = _firstChild->_next;
|
||||
}
|
||||
|
@ -630,6 +661,7 @@ void XMLNode::Unlink( XMLNode* child )
|
|||
|
||||
void XMLNode::DeleteChild( XMLNode* node )
|
||||
{
|
||||
TIXMLASSERT( node->_document == _document );
|
||||
TIXMLASSERT( node->_parent == this );
|
||||
DeleteNode( node );
|
||||
}
|
||||
|
@ -637,8 +669,11 @@ void XMLNode::DeleteChild( XMLNode* node )
|
|||
|
||||
XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
||||
{
|
||||
if (addThis->_document != _document)
|
||||
return 0;
|
||||
TIXMLASSERT( addThis );
|
||||
if ( addThis->_document != _document ) {
|
||||
TIXMLASSERT( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (addThis->_parent)
|
||||
addThis->_parent->Unlink( addThis );
|
||||
|
@ -668,8 +703,11 @@ XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
|||
|
||||
XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis )
|
||||
{
|
||||
if (addThis->_document != _document)
|
||||
return 0;
|
||||
TIXMLASSERT( addThis );
|
||||
if ( addThis->_document != _document ) {
|
||||
TIXMLASSERT( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (addThis->_parent)
|
||||
addThis->_parent->Unlink( addThis );
|
||||
|
@ -700,12 +738,16 @@ XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis )
|
|||
|
||||
XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis )
|
||||
{
|
||||
if (addThis->_document != _document)
|
||||
return 0;
|
||||
TIXMLASSERT( addThis );
|
||||
if ( addThis->_document != _document ) {
|
||||
TIXMLASSERT( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
TIXMLASSERT( afterThis->_parent == this );
|
||||
TIXMLASSERT( afterThis );
|
||||
|
||||
if ( afterThis->_parent != this ) {
|
||||
TIXMLASSERT( false );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -824,7 +866,7 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd )
|
|||
// We read the end tag. Return it to the parent.
|
||||
if ( ele && ele->ClosingType() == XMLElement::CLOSING ) {
|
||||
if ( parentEnd ) {
|
||||
*parentEnd = ele->_value;
|
||||
ele->_value.TransferTo( parentEnd );
|
||||
}
|
||||
node->_memPool->SetTracked(); // created and then immediately deleted.
|
||||
DeleteNode( node );
|
||||
|
@ -921,6 +963,7 @@ bool XMLText::ShallowEqual( const XMLNode* compare ) const
|
|||
|
||||
bool XMLText::Accept( XMLVisitor* visitor ) const
|
||||
{
|
||||
TIXMLASSERT( visitor );
|
||||
return visitor->Visit( *this );
|
||||
}
|
||||
|
||||
|
@ -961,6 +1004,7 @@ XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const
|
|||
|
||||
bool XMLComment::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
TIXMLASSERT( compare );
|
||||
const XMLComment* comment = compare->ToComment();
|
||||
return ( comment && XMLUtil::StringEqual( comment->Value(), Value() ));
|
||||
}
|
||||
|
@ -968,6 +1012,7 @@ bool XMLComment::ShallowEqual( const XMLNode* compare ) const
|
|||
|
||||
bool XMLComment::Accept( XMLVisitor* visitor ) const
|
||||
{
|
||||
TIXMLASSERT( visitor );
|
||||
return visitor->Visit( *this );
|
||||
}
|
||||
|
||||
|
@ -1009,6 +1054,7 @@ XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const
|
|||
|
||||
bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
TIXMLASSERT( compare );
|
||||
const XMLDeclaration* declaration = compare->ToDeclaration();
|
||||
return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() ));
|
||||
}
|
||||
|
@ -1017,6 +1063,7 @@ bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const
|
|||
|
||||
bool XMLDeclaration::Accept( XMLVisitor* visitor ) const
|
||||
{
|
||||
TIXMLASSERT( visitor );
|
||||
return visitor->Visit( *this );
|
||||
}
|
||||
|
||||
|
@ -1057,6 +1104,7 @@ XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const
|
|||
|
||||
bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
TIXMLASSERT( compare );
|
||||
const XMLUnknown* unknown = compare->ToUnknown();
|
||||
return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() ));
|
||||
}
|
||||
|
@ -1064,6 +1112,7 @@ bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const
|
|||
|
||||
bool XMLUnknown::Accept( XMLVisitor* visitor ) const
|
||||
{
|
||||
TIXMLASSERT( visitor );
|
||||
return visitor->Visit( *this );
|
||||
}
|
||||
|
||||
|
@ -1220,17 +1269,6 @@ XMLElement::~XMLElement()
|
|||
}
|
||||
|
||||
|
||||
XMLAttribute* XMLElement::FindAttribute( const char* name )
|
||||
{
|
||||
for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) {
|
||||
if ( XMLUtil::StringEqual( a->Name(), name ) ) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const XMLAttribute* XMLElement::FindAttribute( const char* name ) const
|
||||
{
|
||||
for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) {
|
||||
|
@ -1393,6 +1431,7 @@ XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
|
|||
}
|
||||
}
|
||||
if ( !attrib ) {
|
||||
TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() );
|
||||
attrib = new (_document->_attributePool.Alloc() ) XMLAttribute();
|
||||
attrib->_memPool = &_document->_attributePool;
|
||||
if ( last ) {
|
||||
|
@ -1442,6 +1481,7 @@ char* XMLElement::ParseAttributes( char* p )
|
|||
|
||||
// attribute.
|
||||
if (XMLUtil::IsNameStartChar( *p ) ) {
|
||||
TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() );
|
||||
XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute();
|
||||
attrib->_memPool = &_document->_attributePool;
|
||||
attrib->_memPool->SetTracked();
|
||||
|
@ -1544,6 +1584,7 @@ XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const
|
|||
|
||||
bool XMLElement::ShallowEqual( const XMLNode* compare ) const
|
||||
{
|
||||
TIXMLASSERT( compare );
|
||||
const XMLElement* other = compare->ToElement();
|
||||
if ( other && XMLUtil::StringEqual( other->Value(), Value() )) {
|
||||
|
||||
|
@ -1569,6 +1610,7 @@ bool XMLElement::ShallowEqual( const XMLNode* compare ) const
|
|||
|
||||
bool XMLElement::Accept( XMLVisitor* visitor ) const
|
||||
{
|
||||
TIXMLASSERT( visitor );
|
||||
if ( visitor->VisitEnter( *this, _rootAttribute ) ) {
|
||||
for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) {
|
||||
if ( !node->Accept( visitor ) ) {
|
||||
|
@ -1623,24 +1665,7 @@ XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) :
|
|||
|
||||
XMLDocument::~XMLDocument()
|
||||
{
|
||||
DeleteChildren();
|
||||
delete [] _charBuffer;
|
||||
|
||||
#if 0
|
||||
_textPool.Trace( "text" );
|
||||
_elementPool.Trace( "element" );
|
||||
_commentPool.Trace( "comment" );
|
||||
_attributePool.Trace( "attribute" );
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if ( Error() == false ) {
|
||||
TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() );
|
||||
TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() );
|
||||
TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() );
|
||||
TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() );
|
||||
}
|
||||
#endif
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1648,17 +1673,37 @@ void XMLDocument::Clear()
|
|||
{
|
||||
DeleteChildren();
|
||||
|
||||
#ifdef DEBUG
|
||||
const bool hadError = Error();
|
||||
#endif
|
||||
_errorID = XML_NO_ERROR;
|
||||
_errorStr1 = 0;
|
||||
_errorStr2 = 0;
|
||||
|
||||
delete [] _charBuffer;
|
||||
_charBuffer = 0;
|
||||
|
||||
#if 0
|
||||
_textPool.Trace( "text" );
|
||||
_elementPool.Trace( "element" );
|
||||
_commentPool.Trace( "comment" );
|
||||
_attributePool.Trace( "attribute" );
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if ( !hadError ) {
|
||||
TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() );
|
||||
TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() );
|
||||
TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() );
|
||||
TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
XMLElement* XMLDocument::NewElement( const char* name )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() );
|
||||
XMLElement* ele = new (_elementPool.Alloc()) XMLElement( this );
|
||||
ele->_memPool = &_elementPool;
|
||||
ele->SetName( name );
|
||||
|
@ -1668,6 +1713,7 @@ XMLElement* XMLDocument::NewElement( const char* name )
|
|||
|
||||
XMLComment* XMLDocument::NewComment( const char* str )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLComment ) == _commentPool.ItemSize() );
|
||||
XMLComment* comment = new (_commentPool.Alloc()) XMLComment( this );
|
||||
comment->_memPool = &_commentPool;
|
||||
comment->SetValue( str );
|
||||
|
@ -1677,6 +1723,7 @@ XMLComment* XMLDocument::NewComment( const char* str )
|
|||
|
||||
XMLText* XMLDocument::NewText( const char* str )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );
|
||||
XMLText* text = new (_textPool.Alloc()) XMLText( this );
|
||||
text->_memPool = &_textPool;
|
||||
text->SetValue( str );
|
||||
|
@ -1686,6 +1733,7 @@ XMLText* XMLDocument::NewText( const char* str )
|
|||
|
||||
XMLDeclaration* XMLDocument::NewDeclaration( const char* str )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() );
|
||||
XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration( this );
|
||||
dec->_memPool = &_commentPool;
|
||||
dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" );
|
||||
|
@ -1695,6 +1743,7 @@ XMLDeclaration* XMLDocument::NewDeclaration( const char* str )
|
|||
|
||||
XMLUnknown* XMLDocument::NewUnknown( const char* str )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLUnknown ) == _commentPool.ItemSize() );
|
||||
XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this );
|
||||
unk->_memPool = &_commentPool;
|
||||
unk->SetValue( str );
|
||||
|
@ -1703,6 +1752,8 @@ XMLUnknown* XMLDocument::NewUnknown( const char* str )
|
|||
|
||||
static FILE* callfopen( const char* filepath, const char* mode )
|
||||
{
|
||||
TIXMLASSERT( filepath );
|
||||
TIXMLASSERT( mode );
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
|
||||
FILE* fp = 0;
|
||||
errno_t err = fopen_s( &fp, filepath, mode );
|
||||
|
@ -1714,6 +1765,24 @@ static FILE* callfopen( const char* filepath, const char* mode )
|
|||
#endif
|
||||
return fp;
|
||||
}
|
||||
|
||||
void XMLDocument::DeleteNode( XMLNode* node ) {
|
||||
TIXMLASSERT( node );
|
||||
TIXMLASSERT(node->_document == this );
|
||||
if (node->_parent) {
|
||||
node->_parent->DeleteChild( node );
|
||||
}
|
||||
else {
|
||||
// Isn't in the tree.
|
||||
// Use the parent delete.
|
||||
// Also, we need to mark it tracked: we 'know'
|
||||
// it was never used.
|
||||
node->_memPool->SetTracked();
|
||||
// Call the static XMLNode version:
|
||||
XMLNode::DeleteNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XMLError XMLDocument::LoadFile( const char* filename )
|
||||
{
|
||||
|
@ -1821,6 +1890,16 @@ XMLError XMLDocument::Parse( const char* p, size_t len )
|
|||
|
||||
ptrdiff_t delta = p - start; // skip initial whitespace, BOM, etc.
|
||||
ParseDeep( _charBuffer+delta, 0 );
|
||||
if ( Error() ) {
|
||||
// clean up now essentially dangling memory.
|
||||
// and the parse fail can put objects in the
|
||||
// pools that are dead and inaccessible.
|
||||
DeleteChildren();
|
||||
_elementPool.Clear();
|
||||
_attributePool.Clear();
|
||||
_textPool.Clear();
|
||||
_commentPool.Clear();
|
||||
}
|
||||
return _errorID;
|
||||
}
|
||||
|
||||
|
@ -1837,6 +1916,7 @@ void XMLDocument::Print( XMLPrinter* streamer ) const
|
|||
|
||||
void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 )
|
||||
{
|
||||
TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT );
|
||||
_errorID = error;
|
||||
_errorStr1 = str1;
|
||||
_errorStr2 = str2;
|
||||
|
@ -1844,13 +1924,13 @@ void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 )
|
|||
|
||||
const char* XMLDocument::ErrorName() const
|
||||
{
|
||||
TIXMLASSERT(_errorID >= 0 && _errorID < XML_ERROR_COUNT );
|
||||
TIXMLASSERT( _errorID >= 0 && _errorID < XML_ERROR_COUNT );
|
||||
return _errorNames[_errorID];
|
||||
}
|
||||
|
||||
void XMLDocument::PrintError() const
|
||||
{
|
||||
if ( _errorID ) {
|
||||
if ( Error() ) {
|
||||
static const int LEN = 20;
|
||||
char buf1[LEN] = { 0 };
|
||||
char buf2[LEN] = { 0 };
|
||||
|
@ -1887,6 +1967,8 @@ XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
|
|||
_entityFlag[ (int)entities[i].value ] = true;
|
||||
}
|
||||
}
|
||||
// Clang doesn't like indexing arrays with 'char'
|
||||
// so cast to int. (Looks strange.)
|
||||
_restrictedEntityFlag[(int)'&'] = true;
|
||||
_restrictedEntityFlag[(int)'<'] = true;
|
||||
_restrictedEntityFlag[(int)'>'] = true; // not required, but consistency is nice
|
||||
|
|
|
@ -14,7 +14,6 @@ not claim that you wrote the original software. If you use this
|
|||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
|
@ -25,7 +24,7 @@ distribution.
|
|||
#ifndef TINYXML2_INCLUDED
|
||||
#define TINYXML2_INCLUDED
|
||||
|
||||
#if defined(ANDROID_NDK) || defined(__BORLANDC__)
|
||||
#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
|
||||
# include <ctype.h>
|
||||
# include <limits.h>
|
||||
# include <stdio.h>
|
||||
|
@ -122,9 +121,9 @@ inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
|
|||
/* Versioning, past 1.0.14:
|
||||
http://semver.org/
|
||||
*/
|
||||
static const int TIXML2_MAJOR_VERSION = 2;
|
||||
static const int TIXML2_MINOR_VERSION = 2;
|
||||
static const int TIXML2_PATCH_VERSION = 0;
|
||||
static const int TIXML2_MAJOR_VERSION = 2;
|
||||
static const int TIXML2_MINOR_VERSION = 2;
|
||||
static const int TIXML2_PATCH_VERSION = 0;
|
||||
|
||||
namespace tinyxml2
|
||||
{
|
||||
|
@ -185,6 +184,8 @@ public:
|
|||
char* ParseText( char* in, const char* endTag, int strFlags );
|
||||
char* ParseName( char* in );
|
||||
|
||||
void TransferTo( StrPair* other );
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
void CollapseWhitespace();
|
||||
|
@ -198,6 +199,9 @@ private:
|
|||
int _flags;
|
||||
char* _start;
|
||||
char* _end;
|
||||
|
||||
StrPair( const StrPair& other ); // not supported
|
||||
void operator=( StrPair& other ); // not supported, use TransferTo()
|
||||
};
|
||||
|
||||
|
||||
|
@ -261,7 +265,7 @@ public:
|
|||
return _mem[i];
|
||||
}
|
||||
|
||||
const T& PeekTop() const {
|
||||
const T& PeekTop() const {
|
||||
TIXMLASSERT( _size > 0 );
|
||||
return _mem[ _size - 1];
|
||||
}
|
||||
|
@ -317,6 +321,7 @@ public:
|
|||
virtual void* Alloc() = 0;
|
||||
virtual void Free( void* ) = 0;
|
||||
virtual void SetTracked() = 0;
|
||||
virtual void Clear() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -329,10 +334,20 @@ class MemPoolT : public MemPool
|
|||
public:
|
||||
MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
|
||||
~MemPoolT() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
// Delete the blocks.
|
||||
for( int i=0; i<_blockPtrs.Size(); ++i ) {
|
||||
delete _blockPtrs[i];
|
||||
while( !_blockPtrs.Empty()) {
|
||||
Block* b = _blockPtrs.Pop();
|
||||
delete b;
|
||||
}
|
||||
_root = 0;
|
||||
_currentAllocs = 0;
|
||||
_nAllocs = 0;
|
||||
_maxAllocs = 0;
|
||||
_nUntracked = 0;
|
||||
}
|
||||
|
||||
virtual int ItemSize() const {
|
||||
|
@ -365,6 +380,7 @@ public:
|
|||
_nUntracked++;
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void Free( void* mem ) {
|
||||
if ( !mem ) {
|
||||
return;
|
||||
|
@ -480,7 +496,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// WARNING: must match XMLErrorNames[]
|
||||
// WARNING: must match XMLDocument::_errorNames[]
|
||||
enum XMLError {
|
||||
XML_SUCCESS = 0,
|
||||
XML_NO_ERROR = 0,
|
||||
|
@ -514,10 +530,8 @@ enum XMLError {
|
|||
class XMLUtil
|
||||
{
|
||||
public:
|
||||
// Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
|
||||
// correct, but simple, and usually works.
|
||||
static const char* SkipWhiteSpace( const char* p ) {
|
||||
while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<const unsigned char*>(p) ) ) {
|
||||
while( IsWhiteSpace(*p) ) {
|
||||
++p;
|
||||
}
|
||||
return p;
|
||||
|
@ -525,6 +539,9 @@ public:
|
|||
static char* SkipWhiteSpace( char* p ) {
|
||||
return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
|
||||
}
|
||||
|
||||
// Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
|
||||
// correct, but simple, and usually works.
|
||||
static bool IsWhiteSpace( char p ) {
|
||||
return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
|
||||
}
|
||||
|
@ -1474,7 +1491,9 @@ private:
|
|||
XMLElement( const XMLElement& ); // not supported
|
||||
void operator=( const XMLElement& ); // not supported
|
||||
|
||||
XMLAttribute* FindAttribute( const char* name );
|
||||
XMLAttribute* FindAttribute( const char* name ) {
|
||||
return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
|
||||
}
|
||||
XMLAttribute* FindOrCreateAttribute( const char* name );
|
||||
//void LinkAttribute( XMLAttribute* attrib );
|
||||
char* ParseAttributes( char* p );
|
||||
|
@ -1536,7 +1555,11 @@ public:
|
|||
|
||||
/**
|
||||
Load an XML file from disk. You are responsible
|
||||
for providing and closing the FILE*.
|
||||
for providing and closing the FILE*.
|
||||
|
||||
NOTE: The file should be opened as binary ("rb")
|
||||
not text in order for TinyXML-2 to correctly
|
||||
do newline normalization.
|
||||
|
||||
Returns XML_NO_ERROR (0) on success, or
|
||||
an errorID.
|
||||
|
@ -1646,9 +1669,7 @@ public:
|
|||
Delete a node associated with this document.
|
||||
It will be unlinked from the DOM.
|
||||
*/
|
||||
void DeleteNode( XMLNode* node ) {
|
||||
node->_parent->DeleteChild( node );
|
||||
}
|
||||
void DeleteNode( XMLNode* node );
|
||||
|
||||
void SetError( XMLError error, const char* str1, const char* str2 );
|
||||
|
||||
|
@ -1747,7 +1768,7 @@ private:
|
|||
|
||||
@verbatim
|
||||
XMLHandle docHandle( &document );
|
||||
XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().ToElement();
|
||||
XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
|
||||
if ( child2 )
|
||||
{
|
||||
// do something useful
|
||||
|
|
Loading…
Reference in New Issue