const char* TiXmlCommentA::Parse( const char* p, TiXmlParsingDataA* data ) { TiXmlDocumentA* document = GetDocument(); value = ""; p = SkipWhiteSpace( p ); // TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } const char* startTag = "<!--"; const char* endTag = "-->"; if ( !StringEqual( p, startTag, false ) ) { document->SetError( TIXMLA_ERROR_PARSING_COMMENT, p, data ); return 0; } p += strlen( startTag ); p = ReadText( p, &value, false, endTag, false ); return p; }
const char* TiXmlUnknownA::Parse( const char* p, TiXmlParsingDataA* data ) { TiXmlDocumentA* document = GetDocument(); p = SkipWhiteSpace( p ); // TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } if ( !p || !*p || *p != '<' ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_UNKNOWN, p, data ); return 0; } ++p; value = ""; while ( p && *p && *p != '>' ) { value += *p; ++p; } if ( !p ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_UNKNOWN, 0, 0 ); } if ( *p == '>' ) return p+1; return p; }
const char* TiXmlElementA::ReadValue( const char* p, TiXmlParsingDataA* data ) { TiXmlDocumentA* document = GetDocument(); // Read in text and elements in any order. p = SkipWhiteSpace( p ); while ( p && *p ) { if ( *p != '<' ) { // Take what we have, make a text element. TiXmlTextA* textNode = new TiXmlTextA( "" ); if ( !textNode ) { if ( document ) { document->SetError( TIXMLA_ERROR_OUT_OF_MEMORY, 0, 0 ); } return 0; } p = textNode->Parse( p, data ); if ( !textNode->Blank() ) LinkEndChild( textNode ); else delete textNode; } else { // We hit a '<' // Have we hit a new element or an end tag? if ( StringEqual( p, "</", false ) ) { return p; } else { TiXmlNodeA* node = Identify( p ); if ( node ) { p = node->Parse( p, data ); LinkEndChild( node ); } else { return 0; } } } p = SkipWhiteSpace( p ); } if ( !p ) { if ( document ) document->SetError( TIXMLA_ERROR_READING_ELEMENT_VALUE, 0, 0 ); } return p; }
const char* TiXmlDeclarationA::Parse( const char* p, TiXmlParsingDataA* data ) { p = SkipWhiteSpace( p ); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocumentA* document = GetDocument(); if ( !p || !*p || !StringEqual( p, "<?xml", true ) ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_DECLARATION, 0, 0 ); return 0; } // TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } p += 5; version = ""; encoding = ""; standalone = ""; while ( p && *p ) { if ( *p == '>' ) { ++p; return p; } p = SkipWhiteSpace( p ); if ( StringEqual( p, "version", true ) ) { TiXmlAttributeA attrib; p = attrib.Parse( p, data ); version = attrib.Value(); } else if ( StringEqual( p, "encoding", true ) ) { TiXmlAttributeA attrib; p = attrib.Parse( p, data ); encoding = attrib.Value(); } else if ( StringEqual( p, "standalone", true ) ) { TiXmlAttributeA attrib; p = attrib.Parse( p, data ); standalone = attrib.Value(); } else { // Read over whatever it is. while( p && *p && *p != '>' && !isspace( *p ) ) ++p; } } return 0; }
TiXmlNodeA* TiXmlDocumentA::Clone() const { TiXmlDocumentA* clone = new TiXmlDocumentA(); if ( !clone ) return 0; CopyToClone( clone ); clone->error = error; clone->errorDesc = errorDesc.c_str (); for ( TiXmlNodeA* node = firstChild; node; node = node->NextSibling() ) { clone->LinkEndChild( node->Clone() ); } return clone; }
void TiXmlElementA::SetAttribute( const char * name, const char * _value ) { TiXmlAttributeA* node = attributeSet.Find( name ); if ( node ) { node->SetValue( _value ); return; } TiXmlAttributeA* attrib = new TiXmlAttributeA( name, _value ); if ( attrib ) { attributeSet.Add( attrib ); } else { TiXmlDocumentA* document = GetDocument(); if ( document ) document->SetError( TIXMLA_ERROR_OUT_OF_MEMORY, 0, 0 ); } }
const char* TiXmlElementA::Parse( const char* p, TiXmlParsingDataA* data ) { p = SkipWhiteSpace( p ); TiXmlDocumentA* document = GetDocument(); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_ELEMENT, 0, 0 ); return 0; } // TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } if ( *p != '<' ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_ELEMENT, p, data ); return 0; } p = SkipWhiteSpace( p+1 ); // Read the name. const char* pErr = p; p = ReadName( p, &value ); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data ); return 0; } TIXMLA_STRING endTag ("</"); endTag += value; endTag += ">"; // Check for and read attributes. Also look for an empty // tag or an end tag. while ( p && *p ) { pErr = p; p = SkipWhiteSpace( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_READING_ATTRIBUTES, pErr, data ); return 0; } if ( *p == '/' ) { ++p; // Empty tag. if ( *p != '>' ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_EMPTY, p, data ); return 0; } return (p+1); } else if ( *p == '>' ) { // Done with attributes (if there were any.) // Read the value -- which can include other // elements -- read the end tag, and return. ++p; p = ReadValue( p, data ); // Note this is an Element method, and will set the error if one happens. if ( !p || !*p ) return 0; // We should find the end tag now if ( StringEqual( p, endTag.c_str(), false ) ) { p += endTag.length(); return p; } else { if ( document ) document->SetError( TIXMLA_ERROR_READING_END_TAG, p, data ); return 0; } } else { // Try to read an attribute: TiXmlAttributeA* attrib = new TiXmlAttributeA(); if ( !attrib ) { if ( document ) document->SetError( TIXMLA_ERROR_OUT_OF_MEMORY, pErr, data ); return 0; } attrib->SetDocument( document ); const char* pErr = p; p = attrib->Parse( p, data ); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_ELEMENT, pErr, data ); delete attrib; return 0; } // Handle the strange case of double attributes: TiXmlAttributeA* node = attributeSet.Find( attrib->Name() ); if ( node ) { node->SetValue( attrib->Value() ); delete attrib; return 0; } attributeSet.Add( attrib ); } } return p; }
TiXmlNodeA* TiXmlNodeA::Identify( const char* p ) { TiXmlNodeA* returnNode = 0; p = SkipWhiteSpace( p ); if( !p || !*p || *p != '<' ) { return 0; } TiXmlDocumentA* doc = GetDocument(); p = SkipWhiteSpace( p ); if ( !p || !*p ) { return 0; } // What is this thing? // - Elements start with a letter or underscore, but xml is reserved. // - Comments: <!-- // - Decleration: <?xml // - Everthing else is unknown to tinyxml. // const char* xmlHeader = { "<?xml" }; const char* commentHeader = { "<!--" }; if ( StringEqual( p, xmlHeader, true ) ) { #ifdef DEBUG_PARSER TIXMLA_LOG( "XML parsing Declaration\n" ); #endif returnNode = new TiXmlDeclarationA(); } else if ( isalpha( *(p+1) ) || *(p+1) == '_' ) { #ifdef DEBUG_PARSER TIXMLA_LOG( "XML parsing Element\n" ); #endif returnNode = new TiXmlElementA( "" ); } else if ( StringEqual( p, commentHeader, false ) ) { #ifdef DEBUG_PARSER TIXMLA_LOG( "XML parsing Comment\n" ); #endif returnNode = new TiXmlCommentA(); } else { #ifdef DEBUG_PARSER TIXMLA_LOG( "XML parsing Unknown\n" ); #endif returnNode = new TiXmlUnknownA(); } if ( returnNode ) { // Set the parent, so it can report errors returnNode->parent = this; } else { if ( doc ) doc->SetError( TIXMLA_ERROR_OUT_OF_MEMORY, 0, 0 ); } return returnNode; }