removed the char allocator. Started cleaning up the document code.

This commit is contained in:
Lee Thomason 2012-01-26 18:17:26 -08:00
parent 951d88394c
commit 18d68bdf6b
3 changed files with 76 additions and 21 deletions

View File

@ -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, "\"" );
} }

View File

@ -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;
}; };

View File

@ -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 &amp; That.</element>", "<element>This &amp; That.</element>",
"<element attrib='This&lt;That' />",
0 0
}; };
for( int i=0; test[i]; ++i ) { for( int i=0; test[i]; ++i ) {