From 18d68bdf6b437c4bc74881ce655199ef1042c5b1 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Thu, 26 Jan 2012 18:17:26 -0800 Subject: [PATCH] removed the char allocator. Started cleaning up the document code. --- tinyxml2.cpp | 64 ++++++++++++++++++++++++++++++++++++++++------------ tinyxml2.h | 32 +++++++++++++++++++++----- xmltest.cpp | 1 + 3 files changed, 76 insertions(+), 21 deletions(-) diff --git a/tinyxml2.cpp b/tinyxml2.cpp index a2d0878..f868c91 100644 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -23,14 +23,15 @@ struct Entity { static const int NUM_ENTITIES = 5; static const Entity entities[NUM_ENTITIES] = { - { "quot", 4, '\"' }, + { "quot", 4, DOUBLE_QUOTE }, { "amp", 3, '&' }, - { "apos", 4, '\'' }, + { "apos", 4, SINGLE_QUOTE }, { "lt", 2, '<' }, { "gt", 2, '>' } }; +#if 0 // --------- CharBuffer ----------- // /*static*/ CharBuffer* CharBuffer::Construct( const char* in ) { @@ -47,6 +48,7 @@ static const Entity entities[NUM_ENTITIES] = { free( cb ); } +#endif const char* StrPair::GetStr() @@ -115,7 +117,8 @@ const char* StrPair::GetStr() // --------- 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 ); @@ -126,7 +129,7 @@ char* XMLBase::ParseText( char* p, StrPair* pair, const char* endTag ) // Inner loop of text parsing. while ( *p ) { 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; } ++p; @@ -233,12 +236,18 @@ XMLNode::XMLNode( XMLDocument* doc ) : XMLNode::~XMLNode() { - //printf( "~XMLNode %x\n", this ); + ClearChildren(); +} + + +void XMLNode::ClearChildren() +{ while( firstChild ) { XMLNode* node = firstChild; Unlink( node ); delete node; } + firstChild = lastChild = 0; } @@ -316,7 +325,7 @@ char* XMLNode::ParseDeep( char* p ) // --------- XMLText ---------- // char* XMLText::ParseDeep( char* p ) { - p = ParseText( p, &value, "<" ); + p = ParseText( p, &value, "<", StrPair::TEXT_ELEMENT ); // consumes the end tag. if ( p && *p ) { return p-1; @@ -356,19 +365,19 @@ void XMLComment::Print( XMLStreamer* streamer ) char* XMLComment::ParseDeep( char* p ) { // Comment parses as text. - return ParseText( p, &value, "-->" ); + return ParseText( p, &value, "-->", StrPair::COMMENT ); } // --------- XMLAttribute ---------- // char* XMLAttribute::ParseDeep( char* p ) { - p = ParseText( p, &name, "=" ); + p = ParseText( p, &name, "=", StrPair::ATTRIBUTE_NAME ); if ( !p || !*p ) return 0; char endTag[2] = { *p, 0 }; ++p; - p = ParseText( p, &value, endTag ); + p = ParseText( p, &value, endTag, StrPair::ATTRIBUTE_VALUE ); if ( value.Empty() ) return 0; return p; } @@ -513,24 +522,45 @@ void XMLElement::Print( XMLStreamer* streamer ) // --------- XMLDocument ----------- // XMLDocument::XMLDocument() : - XMLNode( this ), + XMLNode( 0 ), charBuffer( 0 ) { + document = this; // avoid warning about 'this' in initializer list } XMLDocument::~XMLDocument() { + delete [] charBuffer; } +void XMLDocument::InitDocument() +{ + errorID = NO_ERROR; + errorStr1 = 0; + errorStr2 = 0; + + delete [] charBuffer; + charBuffer = 0; + +} + 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; - char* q = ParseDeep( charBuffer->mem ); + char* q = ParseDeep( charBuffer ); return true; } @@ -548,7 +578,10 @@ void XMLDocument::Print( XMLStreamer* streamer ) 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 ) { TIXMLASSERT( elementJustOpened ); - // fixme: supports entities? - fprintf( fp, " %s=\"%s\"", name, value ); + fprintf( fp, " %s=\"", name ); + PrintString( value ); + fprintf( fp, "\"" ); } diff --git a/tinyxml2.h b/tinyxml2.h index f48a5cf..c90e181 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -38,6 +38,7 @@ class XMLText; class XMLStreamer; +/* // internal - move to separate namespace struct CharBuffer { @@ -47,14 +48,19 @@ struct CharBuffer static CharBuffer* Construct( const char* in ); static void Free( CharBuffer* ); }; +*/ -// FIXME: refactor to be the basis for all string handling. class StrPair { public: enum { 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 ) {} @@ -103,7 +109,7 @@ protected: 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 ); + char* ParseText( char* in, StrPair* pair, const char* endTag, int strFlags ); char* ParseName( char* in, StrPair* pair ); char* Identify( XMLDocument* document, char* p, XMLNode** node ); }; @@ -132,7 +138,7 @@ public: protected: XMLNode( XMLDocument* ); - void Unlink( XMLNode* child ); + void ClearChildren(); XMLDocument* document; XMLNode* parent; @@ -145,6 +151,7 @@ protected: XMLNode* next; private: + void Unlink( XMLNode* child ); }; @@ -233,10 +240,13 @@ private: class XMLDocument : public XMLNode { public: - XMLDocument(); + XMLDocument(); ~XMLDocument(); bool Parse( const char* ); + bool Load( const char* ); + bool Load( FILE* ); + void Print( XMLStreamer* streamer=0 ); /* @@ -244,15 +254,25 @@ public: XMLNode* RootElement(); */ enum { + NO_ERROR = 0, ERROR_ELEMENT_MISMATCH, ERROR_PARSING_ELEMENT, ERROR_PARSING_ATTRIBUTE }; 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: XMLDocument( const XMLDocument& ); // intentionally not implemented - CharBuffer* charBuffer; + void InitDocument(); + + bool errorID; + const char* errorStr1; + const char* errorStr2; + char* charBuffer; }; diff --git a/xmltest.cpp b/xmltest.cpp index 6ff4667..8d09bc6 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -42,6 +42,7 @@ int main( int argc, const char* argv ) //"Text inside and bolded in the element.", //"Text inside and bolded in the element.", "This & That.", + "", 0 }; for( int i=0; test[i]; ++i ) {