Lee Thomason 14 лет назад
Родитель
Сommit
1270ae58e4
2 измененных файлов с 66 добавлено и 101 удалено
  1. 8 75
      tinyxml2.cpp
  2. 58 26
      tinyxml2.h

+ 8 - 75
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<ENTITY_RANGE; ++i ) {

+ 58 - 26
tinyxml2.h

@@ -273,34 +273,72 @@ private:
 };
 
 
-class StringStack
+template <class T, int INIT>
+class DynArray
 {
 public:
-	StringStack();
-	~StringStack();
+	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;
+	}
 
-	void Push( const char* str );
-	const char* Pop();
+	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; }
 
-	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
-	int nPositive;		// number of strings with len > 0
+	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 StringPtrStack
+class StringStack
 {
 public:
-	StringPtrStack();
-	~StringPtrStack();
+	StringStack();
+	virtual ~StringStack();
 
 	void Push( const char* str );
 	const char* Pop();
@@ -308,14 +346,8 @@ public:
 	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
+	DynArray< char, 50 > mem;
+	int nPositive;		// number of strings with len > 0
 };
 
 
@@ -345,7 +377,7 @@ private:
 	};
 	bool entityFlag[ENTITY_RANGE];
 
-	StringPtrStack stack;
+	DynArray< const char*, 40 > stack;
 	StringStack text;
 };