more refactoring. cleaning out container classes.
diff --git a/tinyxml2.h b/tinyxml2.h
index 4d2d70e..afd01f4 100644
--- a/tinyxml2.h
+++ b/tinyxml2.h
@@ -1,9 +1,23 @@
 #ifndef TINYXML2_INCLUDED

 #define TINYXML2_INCLUDED

 

+/*

+	TODO

+	- const and non-const versions of API

+	- memory pool the class construction

+	- attribute accessors

+	- node navigation

+	- handles

+	- visit pattern - change streamer?

+	- make constructors protected

+	- hide copy constructor

+	- hide = operator

+*/

+

 #include <limits.h>

 #include <ctype.h>

 #include <stdio.h>

+#include <memory.h>

 

 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)

 	#ifndef DEBUG

@@ -38,18 +52,6 @@
 

 class XMLStreamer;

 

-/*

-// internal - move to separate namespace

-struct CharBuffer

-{

-	size_t  length;

-	char	mem[1];

-

-	static CharBuffer* Construct( const char* in );

-	static void Free( CharBuffer* );

-};

-*/

-

 class StrPair

 {

 public:

@@ -70,6 +72,8 @@
 	const char* GetStr();

 	bool Empty() const { return start == end; }

 

+	void SetInternedStr( const char* str ) { this->start = (char*) str; this->end = 0; this->flags = 0; }

+

 private:

 	enum {

 		NEEDS_FLUSH = 0x100

@@ -82,6 +86,121 @@
 };

 

 

+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;

+	}

+

+	bool Empty() const { return size == 0; }

+	T& operator[](int i) { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }

+	const T& operator[](int i) const { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }

+	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();

+	virtual ~StringStack();

+

+	void Push( const char* str );

+	const char* Pop();

+

+	int NumPositive() const { return nPositive; }

+

+private:

+	DynArray< char, 50 > mem;

+	int nPositive;		// number of strings with len > 0

+};

+*/

+

+/*

+class StringPool

+{

+public:

+	enum { INIT_SIZE=20 };

+

+	StringPool() : size( 0 ) { 

+		const char** mem = pool.PushArr( INIT_SIZE );

+		memset( (void*)mem, 0, sizeof(char)*INIT_SIZE );

+	}

+	~StringPool() {}

+

+	const char* Intern( const char* str );

+

+private:

+	// FNV hash

+	int Hash( const char* s ) {

+		#define FNV_32_PRIME ((int)0x01000193)

+		int hval = 0;

+	    while (*s) {

+			hval *= FNV_32_PRIME;

+			hval ^= (int)*s++;

+		}

+		return hval;

+	}

+

+	int size;

+	DynArray< const char*, INIT_SIZE > pool;		// the hash table

+	StringStack store;								// memory for the interned strings

+};

+*/

+

 class XMLBase

 {

 public:

@@ -125,10 +244,16 @@
 	XMLNode* InsertEndChild( XMLNode* addThis );

 	virtual void Print( XMLStreamer* streamer );

 

+	const char* Value() const			{ return value.GetStr(); }

+	void SetValue( const char* val )	{ value.SetInternedStr( val ); }

+

 	virtual XMLElement* ToElement()		{ return 0; }

 	virtual XMLText*	ToText()		{ return 0; }

 	virtual XMLComment* ToComment()		{ return 0; }

 

+	XMLNode* FirstChild()	{ return firstChild; }

+	XMLElement* FirstChildElement( const char* value=0 );

+

 	// fixme: guarentee null terminator to avoid internal checks

 	virtual char* ParseDeep( char* );

 

@@ -143,6 +268,7 @@
 	XMLDocument*	document;

 	XMLNode*		parent;

 	bool			isTextParent;

+	mutable StrPair			value;

 

 	XMLNode*		firstChild;

 	XMLNode*		lastChild;

@@ -157,29 +283,31 @@
 

 class XMLText : public XMLNode

 {

+	friend class XMLBase;

+	friend class XMLDocument;

 public:

-	XMLText( XMLDocument* doc )	: XMLNode( doc )	{}

 	virtual ~XMLText()								{}

-

 	virtual void Print( XMLStreamer* streamer );

 	const char* Value() { return value.GetStr(); }

+	void SetValue( const char* );

+

 	virtual XMLText*	ToText()		{ return this; }

 

 	char* ParseDeep( char* );

 

 protected:

+	XMLText( XMLDocument* doc )	: XMLNode( doc )	{}

 

 private:

-	StrPair value;

 };

 

 

 class XMLComment : public XMLNode

 {

+	friend class XMLBase;

+	friend class XMLDocument;

 public:

-	XMLComment( XMLDocument* doc );

 	virtual ~XMLComment();

-

 	virtual void Print( XMLStreamer* );

 	virtual XMLComment*	ToComment()		{ return this; }

 

@@ -188,9 +316,10 @@
 	char* ParseDeep( char* );

 

 protected:

+	XMLComment( XMLDocument* doc );

+

 

 private:

-	StrPair value;

 };

 

 

@@ -213,24 +342,29 @@
 

 class XMLElement : public XMLNode

 {

+	friend class XMLBase;

+	friend class XMLDocument;

 public:

-	XMLElement( XMLDocument* doc );

 	virtual ~XMLElement();

 

-	const char* Name() { return name.GetStr(); }

+	const char* Name() const		{ return Value(); }

+	void SetName( const char* str )	{ SetValue( str ); }

+

 	virtual void Print( XMLStreamer* );

 

 	virtual XMLElement* ToElement() { return this; }

-	virtual bool IsClosingElement() const { return closing; }

 

+	// internal:

+	virtual bool IsClosingElement() const { return closing; }

 	char* ParseDeep( char* p );

 

 protected:

+	XMLElement( XMLDocument* doc );

 

 private:

 	char* ParseAttributes( char* p, bool *closedElement );

 

-	StrPair name;

+	mutable StrPair name;

 	bool closing;

 	XMLAttribute* rootAttribute;

 	XMLAttribute* lastAttribute;

@@ -249,6 +383,8 @@
 

 	void Print( XMLStreamer* streamer=0 );

 

+	XMLElement* NewElement( const char* name );

+

 	enum {

 		NO_ERROR = 0,

 		ERROR_ELEMENT_MISMATCH,

@@ -262,6 +398,8 @@
 	const char* GetErrorStr1() const { return errorStr1; }

 	const char* GetErrorStr2() const { return errorStr2; }

 

+//	const char* Intern( const char* );

+

 private:

 	XMLDocument( const XMLDocument& );	// intentionally not implemented

 	void InitDocument();

@@ -270,84 +408,7 @@
 	const char* errorStr1;

 	const char* errorStr2;

 	char* charBuffer;

-};

-

-

-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();

-	virtual ~StringStack();

-

-	void Push( const char* str );

-	const char* Pop();

-

-	int NumPositive() const { return nPositive; }

-

-private:

-	DynArray< char, 50 > mem;

-	int nPositive;		// number of strings with len > 0

+	//StringStack stringPool;

 };

 

 

@@ -368,6 +429,13 @@
 	void SealElement();

 	void PrintSpace( int depth );

 	void PrintString( const char* );	// prints out, after detecting entities.

+	bool TextOnStack() const { 

+		for( int i=0; i<text.Size(); ++i ) { 

+			if ( text[i] == 'T' ) 

+				return true; 

+		} 

+		return false; 

+	}

 

 	FILE* fp;

 	int depth;

@@ -377,8 +445,8 @@
 	};

 	bool entityFlag[ENTITY_RANGE];

 

-	DynArray< const char*, 40 > stack;

-	StringStack text;

+	DynArray< const char*, 10 > stack;

+	DynArray< char, 10 > text;

 };