mirror of https://github.com/AxioDL/tinyxml2.git
removed the char allocator. Started cleaning up the document code.
This commit is contained in:
parent
951d88394c
commit
18d68bdf6b
64
tinyxml2.cpp
64
tinyxml2.cpp
|
@ -23,14 +23,15 @@ struct Entity {
|
||||||
static const int NUM_ENTITIES = 5;
|
static const int NUM_ENTITIES = 5;
|
||||||
static const Entity entities[NUM_ENTITIES] =
|
static const Entity entities[NUM_ENTITIES] =
|
||||||
{
|
{
|
||||||
{ "quot", 4, '\"' },
|
{ "quot", 4, DOUBLE_QUOTE },
|
||||||
{ "amp", 3, '&' },
|
{ "amp", 3, '&' },
|
||||||
{ "apos", 4, '\'' },
|
{ "apos", 4, SINGLE_QUOTE },
|
||||||
{ "lt", 2, '<' },
|
{ "lt", 2, '<' },
|
||||||
{ "gt", 2, '>' }
|
{ "gt", 2, '>' }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
// --------- CharBuffer ----------- //
|
// --------- CharBuffer ----------- //
|
||||||
/*static*/ CharBuffer* CharBuffer::Construct( const char* in )
|
/*static*/ CharBuffer* CharBuffer::Construct( const char* in )
|
||||||
{
|
{
|
||||||
|
@ -47,6 +48,7 @@ static const Entity entities[NUM_ENTITIES] =
|
||||||
{
|
{
|
||||||
free( cb );
|
free( cb );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
const char* StrPair::GetStr()
|
const char* StrPair::GetStr()
|
||||||
|
@ -115,7 +117,8 @@ const char* StrPair::GetStr()
|
||||||
|
|
||||||
|
|
||||||
// --------- XMLBase ----------- //
|
// --------- XMLBase ----------- //
|
||||||
char* XMLBase::ParseText( char* p, StrPair* pair, const char* endTag )
|
// fixme: should take in the entity/newline flags as param
|
||||||
|
char* XMLBase::ParseText( char* p, StrPair* pair, const char* endTag, int strFlags )
|
||||||
{
|
{
|
||||||
TIXMLASSERT( endTag && *endTag );
|
TIXMLASSERT( endTag && *endTag );
|
||||||
|
|
||||||
|
@ -126,7 +129,7 @@ char* XMLBase::ParseText( char* p, StrPair* pair, const char* endTag )
|
||||||
// Inner loop of text parsing.
|
// Inner loop of text parsing.
|
||||||
while ( *p ) {
|
while ( *p ) {
|
||||||
if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
|
if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
|
||||||
pair->Set( start, p, StrPair::NEEDS_ENTITY_PROCESSING | StrPair::NEEDS_NEWLINE_NORMALIZATION );
|
pair->Set( start, p, strFlags );
|
||||||
return p + length;
|
return p + length;
|
||||||
}
|
}
|
||||||
++p;
|
++p;
|
||||||
|
@ -233,12 +236,18 @@ XMLNode::XMLNode( XMLDocument* doc ) :
|
||||||
|
|
||||||
XMLNode::~XMLNode()
|
XMLNode::~XMLNode()
|
||||||
{
|
{
|
||||||
//printf( "~XMLNode %x\n", this );
|
ClearChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLNode::ClearChildren()
|
||||||
|
{
|
||||||
while( firstChild ) {
|
while( firstChild ) {
|
||||||
XMLNode* node = firstChild;
|
XMLNode* node = firstChild;
|
||||||
Unlink( node );
|
Unlink( node );
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
firstChild = lastChild = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -316,7 +325,7 @@ char* XMLNode::ParseDeep( char* p )
|
||||||
// --------- XMLText ---------- //
|
// --------- XMLText ---------- //
|
||||||
char* XMLText::ParseDeep( char* p )
|
char* XMLText::ParseDeep( char* p )
|
||||||
{
|
{
|
||||||
p = ParseText( p, &value, "<" );
|
p = ParseText( p, &value, "<", StrPair::TEXT_ELEMENT );
|
||||||
// consumes the end tag.
|
// consumes the end tag.
|
||||||
if ( p && *p ) {
|
if ( p && *p ) {
|
||||||
return p-1;
|
return p-1;
|
||||||
|
@ -356,19 +365,19 @@ void XMLComment::Print( XMLStreamer* streamer )
|
||||||
char* XMLComment::ParseDeep( char* p )
|
char* XMLComment::ParseDeep( char* p )
|
||||||
{
|
{
|
||||||
// Comment parses as text.
|
// Comment parses as text.
|
||||||
return ParseText( p, &value, "-->" );
|
return ParseText( p, &value, "-->", StrPair::COMMENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------- XMLAttribute ---------- //
|
// --------- XMLAttribute ---------- //
|
||||||
char* XMLAttribute::ParseDeep( char* p )
|
char* XMLAttribute::ParseDeep( char* p )
|
||||||
{
|
{
|
||||||
p = ParseText( p, &name, "=" );
|
p = ParseText( p, &name, "=", StrPair::ATTRIBUTE_NAME );
|
||||||
if ( !p || !*p ) return 0;
|
if ( !p || !*p ) return 0;
|
||||||
|
|
||||||
char endTag[2] = { *p, 0 };
|
char endTag[2] = { *p, 0 };
|
||||||
++p;
|
++p;
|
||||||
p = ParseText( p, &value, endTag );
|
p = ParseText( p, &value, endTag, StrPair::ATTRIBUTE_VALUE );
|
||||||
if ( value.Empty() ) return 0;
|
if ( value.Empty() ) return 0;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -513,24 +522,45 @@ void XMLElement::Print( XMLStreamer* streamer )
|
||||||
|
|
||||||
// --------- XMLDocument ----------- //
|
// --------- XMLDocument ----------- //
|
||||||
XMLDocument::XMLDocument() :
|
XMLDocument::XMLDocument() :
|
||||||
XMLNode( this ),
|
XMLNode( 0 ),
|
||||||
charBuffer( 0 )
|
charBuffer( 0 )
|
||||||
{
|
{
|
||||||
|
document = this; // avoid warning about 'this' in initializer list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XMLDocument::~XMLDocument()
|
XMLDocument::~XMLDocument()
|
||||||
{
|
{
|
||||||
|
delete [] charBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLDocument::InitDocument()
|
||||||
|
{
|
||||||
|
errorID = NO_ERROR;
|
||||||
|
errorStr1 = 0;
|
||||||
|
errorStr2 = 0;
|
||||||
|
|
||||||
|
delete [] charBuffer;
|
||||||
|
charBuffer = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool XMLDocument::Parse( const char* p )
|
bool XMLDocument::Parse( const char* p )
|
||||||
{
|
{
|
||||||
charBuffer = CharBuffer::Construct( p );
|
ClearChildren();
|
||||||
|
InitDocument();
|
||||||
|
|
||||||
|
if ( !p || !*p ) {
|
||||||
|
return true; // correctly parse an empty string?
|
||||||
|
}
|
||||||
|
size_t len = strlen( p );
|
||||||
|
charBuffer = new char[ len+1 ];
|
||||||
|
memcpy( charBuffer, p, len+1 );
|
||||||
XMLNode* node = 0;
|
XMLNode* node = 0;
|
||||||
|
|
||||||
char* q = ParseDeep( charBuffer->mem );
|
char* q = ParseDeep( charBuffer );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,7 +578,10 @@ void XMLDocument::Print( XMLStreamer* streamer )
|
||||||
|
|
||||||
void XMLDocument::SetError( int error, const char* str1, const char* str2 )
|
void XMLDocument::SetError( int error, const char* str1, const char* str2 )
|
||||||
{
|
{
|
||||||
printf( "ERROR: id=%d '%s' '%s'\n", error, str1, str2 );
|
errorID = error;
|
||||||
|
printf( "ERROR: id=%d '%s' '%s'\n", error, str1, str2 ); // fixme: remove
|
||||||
|
errorStr1 = str1;
|
||||||
|
errorStr2 = str2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -682,8 +715,9 @@ void XMLStreamer::OpenElement( const char* name, bool textParent )
|
||||||
void XMLStreamer::PushAttribute( const char* name, const char* value )
|
void XMLStreamer::PushAttribute( const char* name, const char* value )
|
||||||
{
|
{
|
||||||
TIXMLASSERT( elementJustOpened );
|
TIXMLASSERT( elementJustOpened );
|
||||||
// fixme: supports entities?
|
fprintf( fp, " %s=\"", name );
|
||||||
fprintf( fp, " %s=\"%s\"", name, value );
|
PrintString( value );
|
||||||
|
fprintf( fp, "\"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
32
tinyxml2.h
32
tinyxml2.h
|
@ -38,6 +38,7 @@ class XMLText;
|
||||||
|
|
||||||
class XMLStreamer;
|
class XMLStreamer;
|
||||||
|
|
||||||
|
/*
|
||||||
// internal - move to separate namespace
|
// internal - move to separate namespace
|
||||||
struct CharBuffer
|
struct CharBuffer
|
||||||
{
|
{
|
||||||
|
@ -47,14 +48,19 @@ struct CharBuffer
|
||||||
static CharBuffer* Construct( const char* in );
|
static CharBuffer* Construct( const char* in );
|
||||||
static void Free( CharBuffer* );
|
static void Free( CharBuffer* );
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
// FIXME: refactor to be the basis for all string handling.
|
|
||||||
class StrPair
|
class StrPair
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
NEEDS_ENTITY_PROCESSING = 0x01,
|
NEEDS_ENTITY_PROCESSING = 0x01,
|
||||||
NEEDS_NEWLINE_NORMALIZATION = 0x02
|
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 ) {}
|
StrPair() : flags( 0 ), start( 0 ), end( 0 ) {}
|
||||||
|
@ -103,7 +109,7 @@ protected:
|
||||||
inline static int IsAlphaNum( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalnum( anyByte ) : 1; }
|
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; }
|
inline static int IsAlpha( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalpha( anyByte ) : 1; }
|
||||||
|
|
||||||
char* ParseText( char* in, StrPair* pair, const char* endTag );
|
char* ParseText( char* in, StrPair* pair, const char* endTag, int strFlags );
|
||||||
char* ParseName( char* in, StrPair* pair );
|
char* ParseName( char* in, StrPair* pair );
|
||||||
char* Identify( XMLDocument* document, char* p, XMLNode** node );
|
char* Identify( XMLDocument* document, char* p, XMLNode** node );
|
||||||
};
|
};
|
||||||
|
@ -132,7 +138,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
XMLNode( XMLDocument* );
|
XMLNode( XMLDocument* );
|
||||||
void Unlink( XMLNode* child );
|
void ClearChildren();
|
||||||
|
|
||||||
XMLDocument* document;
|
XMLDocument* document;
|
||||||
XMLNode* parent;
|
XMLNode* parent;
|
||||||
|
@ -145,6 +151,7 @@ protected:
|
||||||
XMLNode* next;
|
XMLNode* next;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Unlink( XMLNode* child );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,10 +240,13 @@ private:
|
||||||
class XMLDocument : public XMLNode
|
class XMLDocument : public XMLNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XMLDocument();
|
XMLDocument();
|
||||||
~XMLDocument();
|
~XMLDocument();
|
||||||
|
|
||||||
bool Parse( const char* );
|
bool Parse( const char* );
|
||||||
|
bool Load( const char* );
|
||||||
|
bool Load( FILE* );
|
||||||
|
|
||||||
void Print( XMLStreamer* streamer=0 );
|
void Print( XMLStreamer* streamer=0 );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -244,15 +254,25 @@ public:
|
||||||
XMLNode* RootElement();
|
XMLNode* RootElement();
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
|
NO_ERROR = 0,
|
||||||
ERROR_ELEMENT_MISMATCH,
|
ERROR_ELEMENT_MISMATCH,
|
||||||
ERROR_PARSING_ELEMENT,
|
ERROR_PARSING_ELEMENT,
|
||||||
ERROR_PARSING_ATTRIBUTE
|
ERROR_PARSING_ATTRIBUTE
|
||||||
};
|
};
|
||||||
void SetError( int error, const char* str1, const char* str2 );
|
void SetError( int error, const char* str1, const char* str2 );
|
||||||
|
|
||||||
|
int GetErrorID() const { return errorID; }
|
||||||
|
const char* GetErrorStr1() const { return errorStr1; }
|
||||||
|
const char* GetErrorStr2() const { return errorStr2; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XMLDocument( const XMLDocument& ); // intentionally not implemented
|
XMLDocument( const XMLDocument& ); // intentionally not implemented
|
||||||
CharBuffer* charBuffer;
|
void InitDocument();
|
||||||
|
|
||||||
|
bool errorID;
|
||||||
|
const char* errorStr1;
|
||||||
|
const char* errorStr2;
|
||||||
|
char* charBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ int main( int argc, const char* argv )
|
||||||
//"<element>Text inside and <b>bolded</b> in the element.</element>",
|
//"<element>Text inside and <b>bolded</b> in the element.</element>",
|
||||||
//"<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>",
|
//"<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>",
|
||||||
"<element>This & That.</element>",
|
"<element>This & That.</element>",
|
||||||
|
"<element attrib='This<That' />",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
for( int i=0; test[i]; ++i ) {
|
for( int i=0; test[i]; ++i ) {
|
||||||
|
|
Loading…
Reference in New Issue