24 #ifndef TINYXML2_INCLUDED
25 #define TINYXML2_INCLUDED
27 #if defined(ANDROID_NDK) || defined(__BORLANDC__)
54 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
62 # if defined(_MSC_VER)
63 # define TIXMLASSERT( x ) if ( !(x)) { __debugbreak(); } //if ( !(x)) WinDebugBreak()
64 # elif defined (ANDROID_NDK)
65 # include <android/log.h>
66 # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
69 # define TIXMLASSERT assert
72 # define TIXMLASSERT( x ) {}
76 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
85 inline int TIXML_SNPRINTF(
char* buffer,
size_t size,
const char* format, ... )
88 va_start( va, format );
89 int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
93 #define TIXML_SSCANF sscanf_s
97 #define TIXML_SNPRINTF snprintf
98 #define TIXML_SSCANF sscanf
101 static const int TIXML2_MAJOR_VERSION = 1;
102 static const int TIXML2_MINOR_VERSION = 0;
103 static const int TIXML2_PATCH_VERSION = 11;
113 class XMLDeclaration;
128 NEEDS_ENTITY_PROCESSING = 0x01,
129 NEEDS_NEWLINE_NORMALIZATION = 0x02,
130 COLLAPSE_WHITESPACE = 0x04,
132 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
133 TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
135 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
136 ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
137 COMMENT = NEEDS_NEWLINE_NORMALIZATION
140 StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
143 void Set(
char* start,
char* end,
int flags ) {
147 _flags = flags | NEEDS_FLUSH;
150 const char* GetStr();
153 return _start == _end;
156 void SetInternedStr(
const char* str ) {
158 _start =
const_cast<char*
>(str);
161 void SetStr(
const char* str,
int flags=0 );
163 char* ParseText(
char* in,
const char* endTag,
int strFlags );
164 char* ParseName(
char* in );
168 void CollapseWhitespace();
187 template <
class T,
int INIT>
198 if ( _mem != _pool ) {
204 EnsureCapacity( _size+1 );
208 T* PushArr(
int count ) {
209 EnsureCapacity( _size+count );
210 T* ret = &_mem[_size];
216 return _mem[--_size];
219 void PopArr(
int count ) {
220 TIXMLASSERT( _size >= count );
228 T& operator[](
int i) {
229 TIXMLASSERT( i>= 0 && i < _size );
233 const T& operator[](
int i)
const {
234 TIXMLASSERT( i>= 0 && i < _size );
242 int Capacity()
const {
246 const T* Mem()
const {
255 void EnsureCapacity(
int cap ) {
256 if ( cap > _allocated ) {
257 int newAllocated = cap * 2;
258 T* newMem =
new T[newAllocated];
259 memcpy( newMem, _mem,
sizeof(T)*_size );
260 if ( _mem != _pool ) {
264 _allocated = newAllocated;
285 virtual int ItemSize()
const = 0;
286 virtual void* Alloc() = 0;
287 virtual void Free(
void* ) = 0;
288 virtual void SetTracked() = 0;
299 MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
302 for(
int i=0; i<_blockPtrs.Size(); ++i ) {
303 delete _blockPtrs[i];
307 virtual int ItemSize()
const {
310 int CurrentAllocs()
const {
311 return _currentAllocs;
314 virtual void* Alloc() {
317 Block* block =
new Block();
318 _blockPtrs.Push( block );
320 for(
int i=0; i<COUNT-1; ++i ) {
321 block->chunk[i].next = &block->chunk[i+1];
323 block->chunk[COUNT-1].next = 0;
324 _root = block->chunk;
326 void* result = _root;
330 if ( _currentAllocs > _maxAllocs ) {
331 _maxAllocs = _currentAllocs;
337 virtual void Free(
void* mem ) {
342 Chunk*
chunk = (Chunk*)mem;
344 memset( chunk, 0xfe,
sizeof(Chunk) );
349 void Trace(
const char* name ) {
350 printf(
"Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
351 name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );
358 int Untracked()
const {
371 enum { COUNT = (4*1024)/SIZE };
461 static const char* SkipWhiteSpace(
const char* p ) {
462 while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<const unsigned char*>(p) ) ) {
467 static char* SkipWhiteSpace(
char* p ) {
468 while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<unsigned char*>(p) ) ) {
473 static bool IsWhiteSpace(
char p ) {
474 return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
477 inline static bool IsNameStartChar(
unsigned char ch ) {
478 return ( ( ch < 128 ) ? isalpha( ch ) : 1 )
483 inline static bool IsNameChar(
unsigned char ch ) {
484 return IsNameStartChar( ch )
490 inline static bool StringEqual(
const char* p,
const char* q,
int nChar=INT_MAX ) {
495 while( *p && *q && *p == *q && n<nChar ) {
500 if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
506 inline static int IsUTF8Continuation(
const char p ) {
510 static const char* ReadBOM(
const char* p,
bool* hasBOM );
513 static const char* GetCharacterRef(
const char* p,
char* value,
int* length );
514 static void ConvertUTF32ToUTF8(
unsigned long input,
char* output,
int* length );
517 static void ToStr(
int v,
char* buffer,
int bufferSize );
518 static void ToStr(
unsigned v,
char* buffer,
int bufferSize );
519 static void ToStr(
bool v,
char* buffer,
int bufferSize );
520 static void ToStr(
float v,
char* buffer,
int bufferSize );
521 static void ToStr(
double v,
char* buffer,
int bufferSize );
524 static bool ToInt(
const char* str,
int* value );
525 static bool ToUnsigned(
const char* str,
unsigned* value );
526 static bool ToBool(
const char* str,
bool* value );
527 static bool ToFloat(
const char* str,
float* value );
528 static bool ToDouble(
const char* str,
double* value );
600 virtual const XMLText* ToText()
const {
603 virtual const XMLComment* ToComment()
const {
606 virtual const XMLDocument* ToDocument()
const {
609 virtual const XMLDeclaration* ToDeclaration()
const {
612 virtual const XMLUnknown* ToUnknown()
const {
626 return _value.GetStr();
632 void SetValue(
const char* val,
bool staticMem=
false );
660 const XMLElement* FirstChildElement(
const char* value=0 )
const;
662 XMLElement* FirstChildElement(
const char* value=0 ) {
663 return const_cast<XMLElement*
>(
const_cast<const XMLNode*
>(
this)->FirstChildElement( value ));
672 return const_cast<XMLNode*
>(
const_cast<const XMLNode*
>(
this)->LastChild() );
678 const XMLElement* LastChildElement(
const char* value=0 )
const;
680 XMLElement* LastChildElement(
const char* value=0 ) {
681 return const_cast<XMLElement*
>(
const_cast<const XMLNode*
>(
this)->LastChildElement(value) );
694 const XMLElement* PreviousSiblingElement(
const char* value=0 )
const ;
696 XMLElement* PreviousSiblingElement(
const char* value=0 ) {
697 return const_cast<XMLElement*
>(
const_cast<const XMLNode*
>(
this)->PreviousSiblingElement( value ) );
710 const XMLElement* NextSiblingElement(
const char* value=0 )
const;
712 XMLElement* NextSiblingElement(
const char* value=0 ) {
713 return const_cast<XMLElement*
>(
const_cast<const XMLNode*
>(
this)->NextSiblingElement( value ) );
719 XMLNode* InsertEndChild( XMLNode* addThis );
721 XMLNode* LinkEndChild( XMLNode* addThis ) {
722 return InsertEndChild( addThis );
727 XMLNode* InsertFirstChild( XMLNode* addThis );
731 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
736 void DeleteChildren();
741 void DeleteChild( XMLNode* node );
752 virtual XMLNode* ShallowClone( XMLDocument* document )
const = 0;
760 virtual bool ShallowEqual(
const XMLNode* compare )
const = 0;
784 virtual bool Accept( XMLVisitor* visitor )
const = 0;
787 virtual char* ParseDeep(
char*, StrPair* );
790 XMLNode( XMLDocument* );
792 XMLNode(
const XMLNode& );
793 XMLNode& operator=(
const XMLNode& );
795 XMLDocument* _document;
797 mutable StrPair _value;
799 XMLNode* _firstChild;
807 void Unlink( XMLNode* child );
825 friend class XMLBase;
828 virtual bool Accept(
XMLVisitor* visitor )
const;
833 virtual const XMLText* ToText()
const {
846 char* ParseDeep(
char*,
StrPair* endTag );
848 virtual bool ShallowEqual(
const XMLNode* compare )
const;
852 virtual ~XMLText() {}
853 XMLText(
const XMLText& );
854 XMLText& operator=(
const XMLText& );
873 virtual bool Accept( XMLVisitor* visitor )
const;
875 char* ParseDeep(
char*, StrPair* endTag );
876 virtual XMLNode* ShallowClone( XMLDocument* document )
const;
877 virtual bool ShallowEqual(
const XMLNode* compare )
const;
880 XMLComment( XMLDocument* doc );
881 virtual ~XMLComment();
882 XMLComment(
const XMLComment& );
883 XMLComment& operator=(
const XMLComment& );
911 virtual bool Accept( XMLVisitor* visitor )
const;
913 char* ParseDeep(
char*, StrPair* endTag );
914 virtual XMLNode* ShallowClone( XMLDocument* document )
const;
915 virtual bool ShallowEqual(
const XMLNode* compare )
const;
918 XMLDeclaration( XMLDocument* doc );
919 virtual ~XMLDeclaration();
920 XMLDeclaration(
const XMLDeclaration& );
921 XMLDeclaration& operator=(
const XMLDeclaration& );
943 virtual bool Accept( XMLVisitor* visitor )
const;
945 char* ParseDeep(
char*, StrPair* endTag );
946 virtual XMLNode* ShallowClone( XMLDocument* document )
const;
947 virtual bool ShallowEqual(
const XMLNode* compare )
const;
950 XMLUnknown( XMLDocument* doc );
951 virtual ~XMLUnknown();
952 XMLUnknown(
const XMLUnknown& );
953 XMLUnknown& operator=(
const XMLUnknown& );
962 XML_WRONG_ATTRIBUTE_TYPE,
964 XML_ERROR_FILE_NOT_FOUND,
965 XML_ERROR_FILE_COULD_NOT_BE_OPENED,
966 XML_ERROR_FILE_READ_ERROR,
967 XML_ERROR_ELEMENT_MISMATCH,
968 XML_ERROR_PARSING_ELEMENT,
969 XML_ERROR_PARSING_ATTRIBUTE,
970 XML_ERROR_IDENTIFYING_TAG,
971 XML_ERROR_PARSING_TEXT,
972 XML_ERROR_PARSING_CDATA,
973 XML_ERROR_PARSING_COMMENT,
974 XML_ERROR_PARSING_DECLARATION,
975 XML_ERROR_PARSING_UNKNOWN,
976 XML_ERROR_EMPTY_DOCUMENT,
977 XML_ERROR_MISMATCHED_ELEMENT,
980 XML_CAN_NOT_CONVERT_TEXT,
997 return _name.GetStr();
1001 return _value.GetStr();
1014 QueryIntValue( &i );
1020 QueryUnsignedValue( &i );
1026 QueryBoolValue( &b );
1032 QueryDoubleValue( &d );
1038 QueryFloatValue( &f );
1046 XMLError QueryIntValue(
int* value )
const;
1048 XMLError QueryUnsignedValue(
unsigned int* value )
const;
1050 XMLError QueryBoolValue(
bool* value )
const;
1052 XMLError QueryDoubleValue(
double* value )
const;
1054 XMLError QueryFloatValue(
float* value )
const;
1057 void SetAttribute(
const char* value );
1059 void SetAttribute(
int value );
1061 void SetAttribute(
unsigned value );
1063 void SetAttribute(
bool value );
1065 void SetAttribute(
double value );
1067 void SetAttribute(
float value );
1070 enum { BUF_SIZE = 200 };
1072 XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
1073 virtual ~XMLAttribute() {}
1075 XMLAttribute(
const XMLAttribute& );
1076 void operator=(
const XMLAttribute& );
1077 void SetName(
const char* name );
1079 char* ParseDeep(
char* p,
bool processEntities );
1081 mutable StrPair _name;
1082 mutable StrPair _value;
1083 XMLAttribute* _next;
1094 friend class XMLBase;
1102 void SetName(
const char* str,
bool staticMem=
false ) {
1103 SetValue( str, staticMem );
1109 virtual const XMLElement* ToElement()
const {
1112 virtual bool Accept( XMLVisitor* visitor )
const;
1137 const char* Attribute(
const char* name,
const char* value=0 )
const;
1146 QueryIntAttribute( name, &i );
1152 QueryUnsignedAttribute( name, &i );
1158 QueryBoolAttribute( name, &b );
1164 QueryDoubleAttribute( name, &d );
1170 QueryFloatAttribute( name, &f );
1190 return XML_NO_ATTRIBUTE;
1198 return XML_NO_ATTRIBUTE;
1206 return XML_NO_ATTRIBUTE;
1214 return XML_NO_ATTRIBUTE;
1222 return XML_NO_ATTRIBUTE;
1246 return QueryIntAttribute( name, value );
1249 int QueryAttribute(
const char* name,
unsigned int* value )
const {
1250 return QueryUnsignedAttribute( name, value );
1253 int QueryAttribute(
const char* name,
bool* value )
const {
1254 return QueryBoolAttribute( name, value );
1257 int QueryAttribute(
const char* name,
double* value )
const {
1258 return QueryDoubleAttribute( name, value );
1261 int QueryAttribute(
const char* name,
float* value )
const {
1262 return QueryFloatAttribute( name, value );
1294 void DeleteAttribute(
const char* name );
1298 return _rootAttribute;
1301 const XMLAttribute* FindAttribute(
const char* name )
const;
1331 const char* GetText()
const;
1359 XMLError QueryIntText(
int* ival )
const;
1361 XMLError QueryUnsignedText(
unsigned* uval )
const;
1363 XMLError QueryBoolText(
bool* bval )
const;
1365 XMLError QueryDoubleText(
double* dval )
const;
1367 XMLError QueryFloatText(
float* fval )
const;
1375 int ClosingType()
const {
1376 return _closingType;
1378 char* ParseDeep(
char* p, StrPair* endTag );
1379 virtual XMLNode* ShallowClone( XMLDocument* document )
const;
1380 virtual bool ShallowEqual(
const XMLNode* compare )
const;
1383 XMLElement( XMLDocument* doc );
1384 virtual ~XMLElement();
1385 XMLElement(
const XMLElement& );
1386 void operator=(
const XMLElement& );
1388 XMLAttribute* FindAttribute(
const char* name );
1389 XMLAttribute* FindOrCreateAttribute(
const char* name );
1391 char* ParseAttributes(
char* p );
1397 XMLAttribute* _rootAttribute;
1402 PRESERVE_WHITESPACE,
1417 XMLDocument(
bool processEntities =
true, Whitespace = PRESERVE_WHITESPACE );
1437 XMLError Parse(
const char* xml,
size_t nBytes=(
size_t)(-1) );
1444 XMLError LoadFile(
const char* filename );
1453 XMLError LoadFile( FILE* );
1460 XMLError SaveFile(
const char* filename,
bool compact =
false );
1469 XMLError SaveFile( FILE* fp,
bool compact =
false );
1471 bool ProcessEntities()
const {
1472 return _processEntities;
1474 Whitespace WhitespaceMode()
const {
1494 return FirstChildElement();
1497 return FirstChildElement();
1514 void Print( XMLPrinter* streamer=0 );
1515 virtual bool Accept( XMLVisitor* visitor )
const;
1522 XMLElement* NewElement(
const char* name );
1528 XMLComment* NewComment(
const char* comment );
1534 XMLText* NewText(
const char* text );
1546 XMLDeclaration* NewDeclaration(
const char* text=0 );
1552 XMLUnknown* NewUnknown(
const char* text );
1562 void SetError( XMLError error,
const char* str1,
const char* str2 );
1566 return _errorID != XML_NO_ERROR;
1581 void PrintError()
const;
1587 char* Identify(
char* p,
XMLNode** node );
1601 bool _processEntities;
1603 Whitespace _whitespace;
1604 const char* _errorStr1;
1605 const char* _errorStr2;
1693 return XMLHandle( _node ? _node->FirstChild() : 0 );
1697 return XMLHandle( _node ? _node->FirstChildElement( value ) : 0 );
1701 return XMLHandle( _node ? _node->LastChild() : 0 );
1705 return XMLHandle( _node ? _node->LastChildElement( _value ) : 0 );
1709 return XMLHandle( _node ? _node->PreviousSibling() : 0 );
1713 return XMLHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 );
1717 return XMLHandle( _node ? _node->NextSibling() : 0 );
1721 return XMLHandle( _node ? _node->NextSiblingElement( _value ) : 0 );
1730 return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 );
1734 return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 );
1738 return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 );
1742 return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 );
1775 const XMLConstHandle FirstChildElement(
const char* value=0 )
const {
1776 return XMLConstHandle( _node ? _node->FirstChildElement( value ) : 0 );
1781 const XMLConstHandle LastChildElement(
const char* _value=0 )
const {
1782 return XMLConstHandle( _node ? _node->LastChildElement( _value ) : 0 );
1787 const XMLConstHandle PreviousSiblingElement(
const char* _value=0 )
const {
1788 return XMLConstHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 );
1793 const XMLConstHandle NextSiblingElement(
const char* _value=0 )
const {
1794 return XMLConstHandle( _node ? _node->NextSiblingElement( _value ) : 0 );
1798 const XMLNode* ToNode()
const {
1802 return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 );
1804 const XMLText* ToText()
const {
1805 return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 );
1808 return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 );
1811 return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 );
1870 XMLPrinter( FILE* file=0,
bool compact =
false );
1874 void PushHeader(
bool writeBOM,
bool writeDeclaration );
1878 void OpenElement(
const char* name );
1880 void PushAttribute(
const char* name,
const char* value );
1881 void PushAttribute(
const char* name,
int value );
1882 void PushAttribute(
const char* name,
unsigned value );
1883 void PushAttribute(
const char* name,
bool value );
1884 void PushAttribute(
const char* name,
double value );
1886 void CloseElement();
1889 void PushText(
const char* text,
bool cdata=
false );
1891 void PushText(
int value );
1893 void PushText(
unsigned value );
1895 void PushText(
bool value );
1897 void PushText(
float value );
1899 void PushText(
double value );
1902 void PushComment(
const char* comment );
1904 void PushDeclaration(
const char* value );
1905 void PushUnknown(
const char* value );
1913 virtual bool VisitExit(
const XMLElement& element );
1915 virtual bool Visit(
const XMLText& text );
1916 virtual bool Visit(
const XMLComment& comment );
1918 virtual bool Visit(
const XMLUnknown& unknown );
1925 return _buffer.Mem();
1933 return _buffer.Size();
1938 void PrintSpace(
int depth );
1939 void PrintString(
const char*,
bool restrictedEntitySet );
1940 void Print(
const char* format, ... );
1942 bool _elementJustOpened;
1947 bool _processEntities;
1954 bool _entityFlag[ENTITY_RANGE];
1955 bool _restrictedEntityFlag[ENTITY_RANGE];
1957 DynArray< const char*, 10 > _stack;
1958 DynArray< char, 20 > _buffer;
1960 DynArray< char, 20 > _accumulator;
1968 #endif // TINYXML2_INCLUDED