diff --git a/tinyxml2.cpp b/tinyxml2.cpp index b50a2c3..148c9ad 100644 --- a/tinyxml2.cpp +++ b/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; - if ( needed > 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 +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; };