tinyxml2/tinyxml2.h

231 lines
4.9 KiB
C
Raw Normal View History

2011-12-28 22:36:55 +00:00
#ifndef TINYXML2_INCLUDED
#define TINYXML2_INCLUDED
2011-12-31 22:58:18 +00:00
#include <limits.h>
2012-01-11 23:43:54 +00:00
#include <ctype.h>
#include <stdio.h>
2011-12-31 22:58:18 +00:00
#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 <android/log.h>
#define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
#else
#include <assert.h>
#define TIXMLASSERT assert
#endif
#else
#define TIXMLASSERT( x ) {}
#endif
2011-12-28 22:36:55 +00:00
namespace tinyxml2
{
2012-01-11 23:43:54 +00:00
class XMLDocument;
2012-01-19 01:43:40 +00:00
class XMLElement;
class XMLAttribute;
class XMLComment;
class XMLNode;
2011-12-28 22:36:55 +00:00
2011-12-29 03:42:49 +00:00
// internal - move to separate namespace
struct CharBuffer
{
size_t length;
char mem[1];
static CharBuffer* Construct( const char* in );
static void Free( CharBuffer* );
};
2012-01-20 19:27:56 +00:00
// FIXME: refactor to be the basis for all string handling.
class StrPair
{
2012-01-20 20:55:24 +00:00
public:
2012-01-20 19:27:56 +00:00
enum {
NEEDS_ENTITY_PROCESSING = 0x01,
NEEDS_NEWLINE_NORMALIZATION = 0x02
2012-01-20 19:27:56 +00:00
};
StrPair() : flags( 0 ), start( 0 ), end( 0 ) {}
void Set( char* start, char* end, int flags ) {
2012-01-20 19:27:56 +00:00
this->start = start; this->end = end; this->flags = flags | NEEDS_FLUSH;
}
const char* GetStr();
bool Empty() const { return start == end; }
2012-01-20 19:27:56 +00:00
private:
enum {
NEEDS_FLUSH = 0x100
};
2012-01-20 19:27:56 +00:00
// After parsing, if *end != 0, it can be set to zero.
int flags;
char* start;
2012-01-20 19:27:56 +00:00
char* end;
};
2011-12-29 03:42:49 +00:00
2012-01-19 01:43:40 +00:00
class XMLBase
2011-12-28 22:36:55 +00:00
{
public:
2012-01-19 01:43:40 +00:00
XMLBase() {}
virtual ~XMLBase() {}
2011-12-31 22:58:18 +00:00
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; }
2011-12-31 22:58:18 +00:00
inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
int n = 0;
2012-01-20 20:55:24 +00:00
if ( p == q ) {
return true;
}
2011-12-31 22:58:18 +00:00
while( *p && *q && *p == *q && n<nChar ) {
++p; ++q; ++n;
}
if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
return true;
}
return false;
}
2012-01-19 01:43:40 +00:00
inline static int IsUTF8Continuation( unsigned char p ) { return p & 0x80; }
inline static int IsAlphaNum( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalnum( anyByte ) : 1; }
inline static int IsAlpha( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalpha( anyByte ) : 1; }
char* ParseText( char* in, StrPair* pair, const char* endTag );
2012-01-20 19:27:56 +00:00
char* ParseName( char* in, StrPair* pair );
2012-01-19 01:43:40 +00:00
char* Identify( XMLDocument* document, char* p, XMLNode** node );
};
class XMLNode : public XMLBase
{
friend class XMLDocument;
friend class XMLElement;
public:
virtual ~XMLNode();
XMLNode* InsertEndChild( XMLNode* addThis );
virtual void Print( FILE* cfile, int depth );
virtual XMLElement* ToElement() { return 0; }
virtual char* ParseDeep( char* ) { TIXMLASSERT( 0 ); }
2012-01-19 01:43:40 +00:00
protected:
XMLNode( XMLDocument* );
XMLDocument* document;
XMLNode* parent;
XMLNode* firstChild;
XMLNode* lastChild;
XMLNode* prev;
XMLNode* next;
2011-12-31 22:58:18 +00:00
private:
void PrintSpace( FILE* cfile, int depth ); // prints leading spaces.
2011-12-31 22:58:18 +00:00
2011-12-28 22:36:55 +00:00
};
2011-12-29 03:42:49 +00:00
2011-12-28 22:36:55 +00:00
2011-12-31 22:58:18 +00:00
class XMLComment : public XMLNode
{
public:
XMLComment( XMLDocument* doc );
virtual ~XMLComment();
2011-12-31 22:58:18 +00:00
virtual void Print( FILE* cfile, int depth );
2012-01-11 23:43:54 +00:00
2012-01-20 20:55:24 +00:00
const char* Value() { return value.GetStr(); }
2012-01-19 01:43:40 +00:00
2012-01-11 23:43:54 +00:00
char* ParseDeep( char* );
2012-01-19 01:43:40 +00:00
protected:
private:
2012-01-20 20:55:24 +00:00
StrPair value;
2012-01-19 01:43:40 +00:00
};
class XMLAttribute : public XMLBase
{
friend class XMLElement;
public:
2012-01-20 20:55:24 +00:00
XMLAttribute( XMLElement* element ) : next( 0 ) {}
2012-01-19 01:43:40 +00:00
virtual ~XMLAttribute() {}
2012-01-19 01:55:48 +00:00
virtual void Print( FILE* cfile );
2012-01-19 01:43:40 +00:00
private:
2012-01-19 01:43:40 +00:00
char* ParseDeep( char* p );
2012-01-20 20:55:24 +00:00
StrPair value;
2012-01-19 01:43:40 +00:00
XMLAttribute* next;
};
class XMLElement : public XMLNode
{
public:
XMLElement( XMLDocument* doc );
virtual ~XMLElement();
2012-01-20 20:55:24 +00:00
const char* Name() { return name.GetStr(); }
2012-01-19 01:55:48 +00:00
virtual void Print( FILE* cfile, int depth );
2012-01-19 01:43:40 +00:00
virtual XMLElement* ToElement() { return this; }
bool Closing() const { return closing; }
char* ParseDeep( char* p );
protected:
private:
2012-01-20 20:55:24 +00:00
StrPair name;
2012-01-19 01:43:40 +00:00
bool closing;
XMLAttribute* rootAttribute;
XMLAttribute* lastAttribute;
2011-12-31 22:58:18 +00:00
};
2011-12-28 22:36:55 +00:00
2012-01-19 01:43:40 +00:00
class XMLDocument : public XMLBase
2011-12-28 22:36:55 +00:00
{
public:
XMLDocument();
~XMLDocument();
2011-12-28 22:36:55 +00:00
bool Parse( const char* );
2012-01-11 23:43:54 +00:00
void Print( FILE* cfile=stdout, int depth=0 );
2011-12-28 22:36:55 +00:00
XMLNode* Root() { return root; }
XMLNode* RootElement();
2012-01-19 01:43:40 +00:00
enum {
ERROR_ELEMENT_MISMATCH,
ERROR_PARSING_ELEMENT,
ERROR_PARSING_ATTRIBUTE
};
void SetError( int error, const char* str1, const char* str2 ) {}
2011-12-28 22:36:55 +00:00
private:
XMLDocument( const XMLDocument& ); // intentionally not implemented
2011-12-31 22:58:18 +00:00
XMLNode* root;
2011-12-29 03:42:49 +00:00
CharBuffer* charBuffer;
2011-12-28 22:36:55 +00:00
};
2011-12-29 03:42:49 +00:00
}; // tinyxml2
2011-12-28 22:36:55 +00:00
#endif // TINYXML2_INCLUDED