mirror of https://github.com/AxioDL/tinyxml2.git
cleaned up the memory
This commit is contained in:
parent
7c913cd6db
commit
1270ae58e4
81
tinyxml2.cpp
81
tinyxml2.cpp
|
@ -570,107 +570,40 @@ void XMLDocument::SetError( int error, const char* str1, const char* str2 )
|
|||
|
||||
StringStack::StringStack()
|
||||
{
|
||||
*pool = 0;
|
||||
mem = pool;
|
||||
inUse = 1; // always has a null
|
||||
allocated = INIT;
|
||||
nPositive = 0;
|
||||
mem.Push( 0 ); // start with null. makes later code simpler.
|
||||
}
|
||||
|
||||
|
||||
StringStack::~StringStack()
|
||||
{
|
||||
if ( mem != pool ) {
|
||||
delete [] mem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StringStack::Push( const char* str ) {
|
||||
int needed = strlen( str ) + 1;
|
||||
char* p = mem.PushArr( needed );
|
||||
strcpy( p, str );
|
||||
if ( needed > 1 )
|
||||
nPositive++;
|
||||
if ( inUse+needed >= allocated ) {
|
||||
// fixme: power of 2
|
||||
// less stupid allocation
|
||||
int more = inUse+needed + 1000;
|
||||
|
||||
char* newMem = new char[more];
|
||||
memcpy( newMem, mem, inUse );
|
||||
if ( mem != pool ) {
|
||||
delete [] mem;
|
||||
}
|
||||
mem = newMem;
|
||||
}
|
||||
strcpy( mem+inUse, str );
|
||||
inUse += needed;
|
||||
}
|
||||
|
||||
|
||||
const char* StringStack::Pop() {
|
||||
TIXMLASSERT( inUse > 1 );
|
||||
const char* p = mem+inUse-2;
|
||||
TIXMLASSERT( mem.Size() > 1 );
|
||||
const char* p = mem.Mem() + mem.Size() - 2; // end of final string.
|
||||
if ( *p ) {
|
||||
nPositive--;
|
||||
}
|
||||
while( *p ) { // stack starts with a null, don't need to check for 'mem'
|
||||
TIXMLASSERT( p > mem );
|
||||
TIXMLASSERT( p > mem.Mem() );
|
||||
--p;
|
||||
}
|
||||
inUse = p-mem+1;
|
||||
mem.PopArr( strlen(p)+1 );
|
||||
return p+1;
|
||||
}
|
||||
|
||||
|
||||
StringPtrStack::StringPtrStack()
|
||||
{
|
||||
*pool = 0;
|
||||
mem = pool;
|
||||
inUse = 0;
|
||||
allocated = INIT;
|
||||
nPositive = 0;
|
||||
}
|
||||
|
||||
|
||||
StringPtrStack::~StringPtrStack()
|
||||
{
|
||||
if ( mem != pool ) {
|
||||
delete [] mem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StringPtrStack::Push( const char* str ) {
|
||||
int needed = inUse + 1;
|
||||
if ( str )
|
||||
nPositive++;
|
||||
if ( inUse+needed >= allocated ) {
|
||||
// fixme: power of 2
|
||||
// less stupid allocation
|
||||
int more = inUse+needed + 1000;
|
||||
|
||||
char** newMem = new char*[more];
|
||||
memcpy( newMem, mem, inUse*sizeof(char*) );
|
||||
if ( mem != pool ) {
|
||||
delete [] mem;
|
||||
}
|
||||
mem = newMem;
|
||||
}
|
||||
mem[inUse] = (char*)str;
|
||||
inUse++;
|
||||
}
|
||||
|
||||
|
||||
const char* StringPtrStack::Pop() {
|
||||
TIXMLASSERT( inUse > 0 );
|
||||
inUse--;
|
||||
const char* result = mem[inUse];
|
||||
if ( result )
|
||||
nPositive--;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
XMLStreamer::XMLStreamer( FILE* file ) : fp( file ), depth( 0 ), elementJustOpened( false )
|
||||
{
|
||||
for( int i=0; i<ENTITY_RANGE; ++i ) {
|
||||
|
|
96
tinyxml2.h
96
tinyxml2.h
|
@ -273,11 +273,72 @@ private:
|
|||
};
|
||||
|
||||
|
||||
template <class T, int INIT>
|
||||
class DynArray
|
||||
{
|
||||
public:
|
||||
DynArray< T, INIT >()
|
||||
{
|
||||
mem = pool;
|
||||
allocated = INIT;
|
||||
size = 0;
|
||||
}
|
||||
~DynArray()
|
||||
{
|
||||
if ( mem != pool ) {
|
||||
delete mem;
|
||||
}
|
||||
}
|
||||
void Push( T t )
|
||||
{
|
||||
EnsureCapacity( size+1 );
|
||||
mem[size++] = t;
|
||||
}
|
||||
|
||||
T* PushArr( int count )
|
||||
{
|
||||
EnsureCapacity( size+count );
|
||||
T* ret = &mem[size];
|
||||
size += count;
|
||||
return ret;
|
||||
}
|
||||
T Pop() {
|
||||
return mem[--size];
|
||||
}
|
||||
void PopArr( int count )
|
||||
{
|
||||
TIXMLASSERT( size >= count );
|
||||
size -= count;
|
||||
}
|
||||
int Size() const { return size; }
|
||||
const T* Mem() const { return mem; }
|
||||
T* Mem() { return mem; }
|
||||
|
||||
|
||||
private:
|
||||
void EnsureCapacity( int cap ) {
|
||||
if ( cap > allocated ) {
|
||||
int newAllocated = cap * 2;
|
||||
T* newMem = new T[newAllocated];
|
||||
memcpy( newMem, mem, sizeof(T)*size ); // warning: not using constructors, only works for PODs
|
||||
if ( mem != pool ) delete [] mem;
|
||||
mem = newMem;
|
||||
allocated = newAllocated;
|
||||
}
|
||||
}
|
||||
|
||||
T* mem;
|
||||
T pool[INIT];
|
||||
int allocated; // objects allocated
|
||||
int size; // number objects in use
|
||||
};
|
||||
|
||||
|
||||
class StringStack
|
||||
{
|
||||
public:
|
||||
StringStack();
|
||||
~StringStack();
|
||||
virtual ~StringStack();
|
||||
|
||||
void Push( const char* str );
|
||||
const char* Pop();
|
||||
|
@ -285,40 +346,11 @@ public:
|
|||
int NumPositive() const { return nPositive; }
|
||||
|
||||
private:
|
||||
enum {
|
||||
INIT=10 // fixme, super small for testing
|
||||
};
|
||||
char* mem;
|
||||
char pool[INIT];
|
||||
int inUse; // includes null
|
||||
int allocated; // bytes allocated
|
||||
DynArray< char, 50 > mem;
|
||||
int nPositive; // number of strings with len > 0
|
||||
};
|
||||
|
||||
|
||||
class StringPtrStack
|
||||
{
|
||||
public:
|
||||
StringPtrStack();
|
||||
~StringPtrStack();
|
||||
|
||||
void Push( const char* str );
|
||||
const char* Pop();
|
||||
|
||||
int NumPositive() const { return nPositive; }
|
||||
|
||||
private:
|
||||
enum {
|
||||
INIT=10 // fixme, super small for testing
|
||||
};
|
||||
char** mem;
|
||||
char* pool[INIT];
|
||||
int inUse;
|
||||
int allocated; // bytes allocated
|
||||
int nPositive; // number of non-null pointers
|
||||
};
|
||||
|
||||
|
||||
class XMLStreamer
|
||||
{
|
||||
public:
|
||||
|
@ -345,7 +377,7 @@ private:
|
|||
};
|
||||
bool entityFlag[ENTITY_RANGE];
|
||||
|
||||
StringPtrStack stack;
|
||||
DynArray< const char*, 40 > stack;
|
||||
StringStack text;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue