refactored logic to use the StrPair. Still cleaning up bugs.
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
index 091f328..fe1665b 100644
--- a/tinyxml2.cpp
+++ b/tinyxml2.cpp
@@ -7,10 +7,12 @@
using namespace tinyxml2;
-static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF
+static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF
static const char LF = LINE_FEED;
static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out
static const char CR = CARRIAGE_RETURN;
+static const char SINGLE_QUOTE = '\'';
+static const char DOUBLE_QUOTE = '\"';
// --------- CharBuffer ----------- //
@@ -31,60 +33,66 @@
}
+const char* StrPair::GetStr()
+{
+ if ( flags & NEEDS_FLUSH ) {
+ *end = 0;
+
+ if ( flags & ( NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION ) ) {
+ char* p = start;
+ char* q = start;
+
+ while( p < end ) {
+ if ( *p == CR ) {
+ // CR-LF pair becomes LF
+ // CR alone becomes LF
+ // LF-CR becomes LF
+ if ( *(p+1) == LF ) {
+ p += 2;
+ }
+ else {
+ ++p;
+ }
+ *q = LF;
+ }
+ else if ( *p == LF ) {
+ if ( *(p+1) == CR ) {
+ p += 2;
+ }
+ else {
+ ++p;
+ }
+ *q = LF;
+ }
+ else {
+ *q = *p;
+ ++p;
+ }
+ }
+ }
+ flags = 0;
+ }
+ return start;
+}
+
+
// --------- XMLBase ----------- //
-const char* XMLBase::ParseText( char* p, const char* endTag, char** next )
+char* XMLBase::ParseText( char* p, StrPair* pair, const char* endTag )
{
TIXMLASSERT( endTag && *endTag );
char* start = p;
- char* q = p; // q (target) <= p (src) in same buffer.
char endChar = *endTag;
int length = strlen( endTag );
- char* nextTag = 0;
- *next = 0;
// Inner loop of text parsing.
while ( *p ) {
if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
- *q = 0;
- nextTag = p + length;
+ pair->Set( start, p, StrPair::NEEDS_ENTITY_PROCESSING | StrPair::NEEDS_NEWLINE_NORMALIZATION );
break;
}
- else if ( *p == CR ) {
- // CR-LF pair becomes LF
- // CR alone becomes LF
- // LF-CR becomes LF
- if ( *(p+1) == LF ) {
- p += 2;
- }
- else {
- ++p;
- }
- *q = LF;
- }
- else if ( *p == LF ) {
- if ( *(p+1) == CR ) {
- p += 2;
- }
- else {
- ++p;
- }
- *q = LF;
- }
- else {
- *q = *p;
- ++p;
- }
- ++q;
}
-
- // Error? If we don't have a text tag, something went wrong. (Although
- // what the nextTag points at may be null.)
- if ( nextTag == 0 ) {
- return 0;
- }
- *next = nextTag;
- return start;
+ return p;
}
@@ -92,7 +100,6 @@
{
char* start = p;
char* nextTag = 0;
- *next = 0;
start = p;
if ( !start || !(*start) ) {
@@ -112,11 +119,10 @@
{
++p;
}
- *p = 0;
if ( p > start ) {
- *next = p+1;
- return start;
+ pair->Set( start, p, 0 );
+ return p;
}
return 0;
}
@@ -241,7 +247,7 @@
// --------- XMLComment ---------- //
-XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ), value( 0 )
+XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc )
{
}
@@ -261,8 +267,7 @@
char* XMLComment::ParseDeep( char* p )
{
// Comment parses as text.
- value = ParseText( p, "-->", &p );
- return p;
+ return ParseText( p, &value, "-->" );
}
@@ -271,8 +276,8 @@
{
char endTag[2] = { *p, 0 };
++p;
- value = ParseText( p, endTag, &p );
- if ( !value ) return 0;
+ p = ParseText( p, &value, endTag );
+ if ( value.Empty() ) return 0;
return p;
}
@@ -285,7 +290,6 @@
// --------- XMLElement ---------- //
XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),
- name( 0 ),
closing( false ),
rootAttribute( 0 ),
lastAttribute( 0 )
@@ -326,25 +330,24 @@
++p;
}
- name = ParseName( p, &p );
- if ( !name ) return 0;
+ p = ParseName( p, &name );
+ if ( name.Empty() ) return 0;
// Read the attributes.
while( p ) {
p = SkipWhiteSpace( p );
if ( !p || !(*p) ) {
- document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, name );
+ document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, name.GetStr() );
return 0;
}
- const char* saveP = p;
// attribute.
- if ( *p == '\'' || *p == '\"' ) {
+ if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
XMLAttribute* attrib = new XMLAttribute( this );
p = attrib->ParseDeep( p );
if ( !p ) {
delete attrib;
- document->SetError( XMLDocument::ERROR_PARSING_ATTRIBUTE, start, saveP );
+ document->SetError( XMLDocument::ERROR_PARSING_ATTRIBUTE, start, p );
return 0;
}
if ( rootAttribute ) {
@@ -356,36 +359,41 @@
rootAttribute = lastAttribute = attrib;
}
}
+ // end of the tag
else if ( *p == '/' && *(p+1) == '>' ) {
- // end tag.
if ( closing ) {
document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, p );
return 0;
}
return p+2; // done; sealed element.
}
+ // end of the tag
else if ( *p == '>' ) {
++p;
break;
}
+ else {
+ document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, p );
+ return 0;
+ }
}
while( p && *p ) {
XMLNode* node = 0;
p = Identify( document, p, &node );
if ( p && node ) {
- node->ParseDeep( p );
+ p = node->ParseDeep( p );
XMLElement* element = node->ToElement();
if ( element && element->Closing() ) {
if ( StringEqual( element->Name(), this->Name() ) ) {
// All good, this is closing tag.
delete node;
- p = 0;
}
else {
document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, p );
delete node;
+ p = 0;
}
return p;
}