#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 #include #include #include #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__) #ifndef DEBUG #define DEBUG #endif #endif #if defined(DEBUG) #if defined(_MSC_VER) #define TIXMLASSERT( x ) if ( !(x)) { _asm { int 3 } } //if ( !(x)) WinDebugBreak() #elif defined (ANDROID_NDK) #include #define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } #else #include #define TIXMLASSERT assert #endif #else #define TIXMLASSERT( x ) {} #endif namespace tinyxml2 { class XMLDocument; class XMLElement; class XMLAttribute; class XMLComment; class XMLNode; class XMLText; class XMLStreamer; class StrPair { public: enum { NEEDS_ENTITY_PROCESSING = 0x01, NEEDS_NEWLINE_NORMALIZATION = 0x02, TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, ATTRIBUTE_NAME = 0, ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, COMMENT = NEEDS_NEWLINE_NORMALIZATION, }; StrPair() : flags( 0 ), start( 0 ), end( 0 ) {} void Set( char* start, char* end, int flags ) { this->start = start; this->end = end; this->flags = flags | NEEDS_FLUSH; } 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 }; // After parsing, if *end != 0, it can be set to zero. int flags; char* start; char* end; }; template 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: XMLBase() {} virtual ~XMLBase() {} protected: static const char* SkipWhiteSpace( const char* p ) { while( isspace( *p ) ) { ++p; } return p; } static char* SkipWhiteSpace( char* p ) { while( isspace( *p ) ) { ++p; } return p; } inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { int n = 0; if ( p == q ) { return true; } while( *p && *q && *p == *q && n stack; DynArray< char, 10 > text; }; }; // tinyxml2 #endif // TINYXML2_INCLUDED