mirror of https://github.com/AxioDL/tinyxml2.git
Merge branch 'properStrPairAssignment' of https://github.com/Dmitry-Me/tinyxml2 into Dmitry-Me-properStrPairAssignment
This commit is contained in:
commit
327d5c142e
93
tinyxml2.cpp
93
tinyxml2.cpp
|
@ -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 ) {
|
||||
|
@ -212,12 +235,13 @@ const char* StrPair::GetStr()
|
|||
else {
|
||||
int i=0;
|
||||
for(; i<NUM_ENTITIES; ++i ) {
|
||||
if ( strncmp( p+1, entities[i].pattern, entities[i].length ) == 0
|
||||
&& *(p+entities[i].length+1) == ';' ) {
|
||||
// Found an entity convert;
|
||||
*q = entities[i].value;
|
||||
const Entity& entity = entities[i];
|
||||
if ( strncmp( p + 1, entity.pattern, entity.length ) == 0
|
||||
&& *( p + entity.length + 1 ) == ';' ) {
|
||||
// Found an entity - convert.
|
||||
*q = entity.value;
|
||||
++q;
|
||||
p += entities[i].length + 2;
|
||||
p += entity.length + 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -823,7 +847,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 );
|
||||
|
@ -1257,7 +1281,7 @@ const char* XMLElement::Attribute( const char* name, const char* value ) const
|
|||
const char* XMLElement::GetText() const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
return FirstChild()->ToText()->Value();
|
||||
return FirstChild()->Value();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1317,7 +1341,7 @@ void XMLElement::SetText( double v )
|
|||
XMLError XMLElement::QueryIntText( int* ival ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
const char* t = FirstChild()->Value();
|
||||
if ( XMLUtil::ToInt( t, ival ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
|
@ -1330,7 +1354,7 @@ XMLError XMLElement::QueryIntText( int* ival ) const
|
|||
XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
const char* t = FirstChild()->Value();
|
||||
if ( XMLUtil::ToUnsigned( t, uval ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
|
@ -1343,7 +1367,7 @@ XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const
|
|||
XMLError XMLElement::QueryBoolText( bool* bval ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
const char* t = FirstChild()->Value();
|
||||
if ( XMLUtil::ToBool( t, bval ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
|
@ -1356,7 +1380,7 @@ XMLError XMLElement::QueryBoolText( bool* bval ) const
|
|||
XMLError XMLElement::QueryDoubleText( double* dval ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
const char* t = FirstChild()->Value();
|
||||
if ( XMLUtil::ToDouble( t, dval ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
|
@ -1369,7 +1393,7 @@ XMLError XMLElement::QueryDoubleText( double* dval ) const
|
|||
XMLError XMLElement::QueryFloatText( float* fval ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
const char* t = FirstChild()->Value();
|
||||
if ( XMLUtil::ToFloat( t, fval ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
|
@ -1622,24 +1646,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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1653,6 +1660,22 @@ void XMLDocument::Clear()
|
|||
|
||||
delete [] _charBuffer;
|
||||
_charBuffer = 0;
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
|
@ -1820,6 +1843,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 (_errorID) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
37
tinyxml2.h
37
tinyxml2.h
|
@ -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.
|
||||
|
||||
|
@ -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 operator=(const StrPair& rhs);
|
||||
|
||||
|
@ -200,6 +201,9 @@ private:
|
|||
int _flags;
|
||||
char* _start;
|
||||
char* _end;
|
||||
|
||||
StrPair( const StrPair& other ); // not supported
|
||||
void operator=( StrPair& other ); // not supported, use TransferTo()
|
||||
};
|
||||
|
||||
|
||||
|
@ -263,7 +267,7 @@ public:
|
|||
return _mem[i];
|
||||
}
|
||||
|
||||
const T& PeekTop() const {
|
||||
const T& PeekTop() const {
|
||||
TIXMLASSERT( _size > 0 );
|
||||
return _mem[ _size - 1];
|
||||
}
|
||||
|
@ -319,6 +323,7 @@ public:
|
|||
virtual void* Alloc() = 0;
|
||||
virtual void Free( void* ) = 0;
|
||||
virtual void SetTracked() = 0;
|
||||
virtual void Clear() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -331,10 +336,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 {
|
||||
|
@ -367,6 +382,7 @@ public:
|
|||
_nUntracked++;
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void Free( void* mem ) {
|
||||
if ( !mem ) {
|
||||
return;
|
||||
|
@ -516,10 +532,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;
|
||||
|
@ -527,6 +541,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) );
|
||||
}
|
||||
|
|
|
@ -96,6 +96,9 @@
|
|||
/* Begin PBXProject section */
|
||||
037AE058151CCC5200E0F29F /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0610;
|
||||
};
|
||||
buildConfigurationList = 037AE05B151CCC5200E0F29F /* Build configuration list for PBXProject "tinyxml2" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
|
@ -134,6 +137,8 @@
|
|||
buildSettings = {
|
||||
CONFIGURATION_BUILD_DIR = "$(SYMROOT)/Debug";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = DEBUG;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SYMROOT = build;
|
||||
};
|
||||
name = Debug;
|
||||
|
@ -156,6 +161,7 @@
|
|||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
INSTALL_PATH = /usr/local/bin;
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = xmltest;
|
||||
};
|
||||
|
@ -171,6 +177,7 @@
|
|||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
INSTALL_PATH = /usr/local/bin;
|
||||
MACOSX_DEPLOYMENT_TARGET = "";
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = tinyxml2;
|
||||
ZERO_LINK = NO;
|
||||
|
|
19
xmltest.cpp
19
xmltest.cpp
|
@ -279,6 +279,8 @@ int main( int argc, const char ** argv )
|
|||
{
|
||||
#if defined( _MSC_VER ) && defined( DEBUG )
|
||||
_CrtMemCheckpoint( &startMemState );
|
||||
// Enable MS Visual C++ debug heap memory leaks dump on exit
|
||||
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) || defined(MINGW32) || defined(__MINGW32__)
|
||||
|
@ -1371,7 +1373,22 @@ int main( int argc, const char ** argv )
|
|||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
{
|
||||
// Issue #184
|
||||
// If it doesn't assert, it passes. Caused by objects
|
||||
// getting created during parsing which are then
|
||||
// inaccessible in the memory pools.
|
||||
{
|
||||
XMLDocument doc;
|
||||
doc.Parse("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test>");
|
||||
}
|
||||
{
|
||||
XMLDocument doc;
|
||||
doc.Parse("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test>");
|
||||
doc.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------- Performance tracking --------------
|
||||
|
|
Loading…
Reference in New Issue