const char* TiXmlDeclaration::Parse( const char* p ) { p = SkipWhiteSpace( p ); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocument* document = GetDocument(); if ( !p || !*p || !StringEqual( p, "<?xml", true ) ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION ); return 0; } p += 5; // const char* start = p+5; // const char* end = strstr( start, "?>" ); version = ""; encoding = ""; standalone = ""; while ( p && *p ) { if ( *p == '>' ) { ++p; return p; } p = SkipWhiteSpace( p ); if ( StringEqual( p, "version", true ) ) { // p += 7; TiXmlAttribute attrib; p = attrib.Parse( p ); version = attrib.Value(); } else if ( StringEqual( p, "encoding", true ) ) { // p += 8; TiXmlAttribute attrib; p = attrib.Parse( p ); encoding = attrib.Value(); } else if ( StringEqual( p, "standalone", true ) ) { // p += 10; TiXmlAttribute attrib; p = attrib.Parse( p ); standalone = attrib.Value(); } else { // Read over whatever it is. while( p && *p && *p != '>' && !isspace( *p ) ) ++p; } } return 0; }
const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data ) { p = SkipWhiteSpace( p ); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocument* document = GetDocument(); if ( !p || !*p || !StringEqual( p, "<?xml", true ) ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0 ); return 0; } // TiXmlParsingData 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 ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data ); version = attrib.Value(); } else if ( StringEqual( p, "encoding", true ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data ); encoding = attrib.Value(); } else if ( StringEqual( p, "standalone", true ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data ); standalone = attrib.Value(); } else { // Read over whatever it is. while( p && *p && *p != '>' && !isspace( *p ) ) ++p; } } return 0; }
const TIXML_CHAR* TiXmlDeclaration::Parse( const TIXML_CHAR* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) { p = SkipWhiteSpace( p, _encoding ); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocument* document = GetDocument(); if ( !p || !*p || !StringEqual( p, _TIXML_L("<?xml"), true, _encoding ) ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); return 0; } if ( data ) { data->Stamp( p, _encoding ); location = data->Cursor(); } p += 5; version = _TIXML_L(""); encoding = _TIXML_L(""); standalone = _TIXML_L(""); while ( p && *p ) { if ( *p == _TIXML_L('>') ) { ++p; return p; } p = SkipWhiteSpace( p, _encoding ); if ( StringEqual( p, _TIXML_L("version"), true, _encoding ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data, _encoding ); version = attrib.Value(); } else if ( StringEqual( p, _TIXML_L("encoding"), true, _encoding ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data, _encoding ); encoding = attrib.Value(); } else if ( StringEqual( p, _TIXML_L("standalone"), true, _encoding ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data, _encoding ); standalone = attrib.Value(); } else { // Read over whatever it is. while( p && *p && *p != _TIXML_L('>') && !IsWhiteSpace( *p ) ) ++p; } } return 0; }
const char* TiXmlDeclaration::Parse( const char* p ) { // Find the beginning, find the end, and look for // the stuff in-between. const char* start = p+4; const char* end = strstr( start, "?>" ); // Be nice to the user: if ( !end ) { end = strstr( start, ">" ); end++; } else { end += 2; } if ( !end ) { TiXmlDocument* document = GetDocument(); if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION ); return 0; } else { const char* p; p = strstr( start, "version" ); if ( p && p < end ) { TiXmlAttribute attrib; attrib.Parse( p ); version = attrib.Value(); } p = strstr( start, "encoding" ); if ( p && p < end ) { TiXmlAttribute attrib; attrib.Parse( p ); encoding = attrib.Value(); } p = strstr( start, "standalone" ); if ( p && p < end ) { TiXmlAttribute attrib; attrib.Parse( p ); standalone = attrib.Value(); } } return end; }
const char* TiXmlStylesheetReference::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) { p = SkipWhiteSpace( p, _encoding ); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocument* document = GetDocument(); if ( !p || !*p || !StringEqual( p, "<?xml-stylesheet", true, _encoding ) ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); return 0; } if ( data ) { data->Stamp( p, _encoding ); location = data->Cursor(); } p += 5; type = ""; href = ""; while ( p && *p ) { if ( *p == '>' ) { ++p; return p; } p = SkipWhiteSpace( p, _encoding ); if ( StringEqual( p, "type", true, _encoding ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data, _encoding ); type = attrib.Value(); } else if ( StringEqual( p, "href", true, _encoding ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data, _encoding ); href = attrib.Value(); } else { // Read over whatever it is. while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) ++p; } } return 0; }
const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) { p = SkipWhiteSpace( p, encoding ); TiXmlDocument* document = GetDocument(); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding ); return 0; } if ( data ) { data->Stamp( p, encoding ); location = data->Cursor(); } if ( *p != '<' ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding ); return 0; } p = SkipWhiteSpace( p+1, encoding ); // Read the name. const char* pErr = p; p = ReadName( p, &value, encoding ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding ); return 0; } TIXML_STRING endTag ("</"); endTag += value; // Check for and read attributes. Also look for an empty // tag or an end tag. while ( p && *p ) { pErr = p; p = SkipWhiteSpace( p, encoding ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); return 0; } if ( *p == '/' ) { ++p; // Empty tag. if ( *p != '>' ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding ); 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, encoding ); // Note this is an Element method, and will set the error if one happens. if ( !p || !*p ) { // We were looking for the end tag, but found nothing. // Fix for [ 1663758 ] Failure to report error on bad XML if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding ); return 0; } // We should find the end tag now // note that: // </foo > and // </foo> // are both valid end tags. if ( StringEqual( p, endTag.c_str(), false, encoding ) ) { p += endTag.length(); p = SkipWhiteSpace( p, encoding ); if ( p && *p && *p == '>' ) { ++p; return p; } if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding ); return 0; } else { if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding ); return 0; } } else { // Try to read an attribute: TiXmlAttribute* attrib = new TiXmlAttribute(); if ( !attrib ) { return 0; } attrib->SetDocument( document ); pErr = p; p = attrib->Parse( p, data, encoding ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding ); delete attrib; return 0; } // Handle the strange case of double attributes: #ifdef TIXML_USE_STL TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() ); #else TiXmlAttribute* node = attributeSet.Find( attrib->Name() ); #endif if ( node ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding ); delete attrib; return 0; } attributeSet.Add( attrib ); } } return p; }
const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data ) { p = SkipWhiteSpace( p ); TiXmlDocument* document = GetDocument(); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0 ); return 0; } // TiXmlParsingData data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } if ( *p != '<' ) { if ( document ) document->SetError( TIXML_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( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data ); return 0; } TIXML_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( TIXML_ERROR_READING_ATTRIBUTES, pErr, data ); return 0; } if ( *p == '/' ) { ++p; // Empty tag. if ( *p != '>' ) { if ( document ) document->SetError( TIXML_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( TIXML_ERROR_READING_END_TAG, p, data ); return 0; } } else { // Try to read an attribute: TiXmlAttribute* attrib = new TiXmlAttribute(); if ( !attrib ) { if ( document ) document->SetError( TIXML_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( TIXML_ERROR_PARSING_ELEMENT, pErr, data ); delete attrib; return 0; } // Handle the strange case of double attributes: TiXmlAttribute* node = attributeSet.Find( attrib->Name() ); if ( node ) { node->SetValue( attrib->Value() ); delete attrib; return 0; } attributeSet.Add( attrib ); } } return p; }
const char* TiXmlElement::Parse( const char* p ) { p = SkipWhiteSpace( p ); TiXmlDocument* document = GetDocument(); if ( !p || !*p || *p != '<' ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT ); return false; } p = SkipWhiteSpace( p+1 ); // Read the name. p = ReadName( p, &value ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME ); return false; } TIXML_STRING endTag ("</"); endTag += value; endTag += ">"; // Check for and read attributes. Also look for an empty // tag or an end tag. while ( p && *p ) { p = SkipWhiteSpace( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES ); return 0; } if ( *p == '/' ) { ++p; // Empty tag. if ( *p != '>' ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY ); 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 ); // 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( TIXML_ERROR_READING_END_TAG ); return 0; } } else { // Try to read an element: TiXmlAttribute attrib; attrib.SetDocument( document ); p = attrib.Parse( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT ); return 0; } SetAttribute( attrib.Name(), attrib.Value() ); } } return p; }
const char* TiXmlElement::Parse( const char* p ) { TiXmlDocument* document = GetDocument(); p = SkipWhiteSpace( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT ); return 0; } // Read the name. p = ReadName( p, &value ); if ( !p ) { if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME ); return 0; } std::string endTag = "</"; endTag += value; endTag += ">"; // Check for and read attributes. Also look for an empty // tag or an end tag. while ( p && *p ) { p = SkipWhiteSpace( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES ); return 0; } if ( *p == '/' ) { // Empty tag. if ( *(p+1) != '>' ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY ); return 0; } return p+2; } 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 = ReadValue( p+1 ); // Note this is an Element method, and will set the error if one happens. if ( !p ) return 0; // We should find the end tag now std::string buf( p, endTag.size() ); if ( endTag == buf ) { return p+endTag.size(); } else { if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG ); return 0; } } else { // Try to read an element: TiXmlAttribute attrib; attrib.SetDocument( document ); p = attrib.Parse( p ); if ( p ) { SetAttribute( attrib.Name(), attrib.Value() ); } } } return 0; }