|
Packit |
47f805 |
/*
|
|
Packit |
47f805 |
Copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
This software is provided 'as-is', without any express or implied
|
|
Packit |
47f805 |
warranty. In no event will the authors be held liable for any
|
|
Packit |
47f805 |
damages arising from the use of this software.
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
Permission is granted to anyone to use this software for any
|
|
Packit |
47f805 |
purpose, including commercial applications, and to alter it and
|
|
Packit |
47f805 |
redistribute it freely, subject to the following restrictions:
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
1. The origin of this software must not be misrepresented; you must
|
|
Packit |
47f805 |
not claim that you wrote the original software. If you use this
|
|
Packit |
47f805 |
software in a product, an acknowledgment in the product documentation
|
|
Packit |
47f805 |
would be appreciated but is not required.
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
2. Altered source versions must be plainly marked as such, and
|
|
Packit |
47f805 |
must not be misrepresented as being the original software.
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
3. This notice may not be removed or altered from any source
|
|
Packit |
47f805 |
distribution.
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include "tinyxml.h"
|
|
Packit |
47f805 |
#include <ctype.h>
|
|
Packit |
47f805 |
#include <strstream>
|
|
Packit |
47f805 |
using namespace std;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//#define DEBUG_PARSER
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] =
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
{ "&", 5, '&' },
|
|
Packit |
47f805 |
{ "<", 4, '<' },
|
|
Packit |
47f805 |
{ ">", 4, '>' },
|
|
Packit |
47f805 |
{ """, 6, '\"' },
|
|
Packit |
47f805 |
{ "'", 6, '\'' }
|
|
Packit |
47f805 |
};
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlBase::SkipWhiteSpace( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( !p || !*p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
while ( p && *p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( isspace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space.
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream* in, std::string* tag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
for( ;; )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( !in->good() ) return false;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
int c = in->peek();
|
|
Packit |
47f805 |
if ( !IsWhiteSpace( c ) )
|
|
Packit |
47f805 |
return true;
|
|
Packit |
47f805 |
*tag += in->get();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*static*/ bool TiXmlBase::StreamTo( std::istream* in, int character, std::string* tag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
while ( in->good() )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int c = in->peek();
|
|
Packit |
47f805 |
if ( c == character )
|
|
Packit |
47f805 |
return true;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
in->get();
|
|
Packit |
47f805 |
*tag += c;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return false;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlBase::ReadName( const char* p, string* name )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*name = "";
|
|
Packit |
47f805 |
assert( p );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Names start with letters or underscores.
|
|
Packit |
47f805 |
// After that, they can be letters, underscores, numbers,
|
|
Packit |
47f805 |
// hyphens, or colons. (Colons are valid ony for namespaces,
|
|
Packit |
47f805 |
// but tinyxml can't tell namespaces from names.)
|
|
Packit |
47f805 |
if ( p && *p
|
|
Packit |
47f805 |
&& ( isalpha( (unsigned char) *p ) || *p == '_' ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
while( p && *p
|
|
Packit |
47f805 |
&& ( isalnum( (unsigned char ) *p )
|
|
Packit |
47f805 |
|| *p == '_'
|
|
Packit |
47f805 |
|| *p == '-'
|
|
Packit |
47f805 |
|| *p == ':' ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
(*name) += *p;
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlBase::GetEntity( const char* p, char* value )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Presume an entity, and pull it out.
|
|
Packit |
47f805 |
string ent;
|
|
Packit |
47f805 |
int i;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Ignore the &#x entities.
|
|
Packit |
47f805 |
if ( strncmp( "&#x", p, 3 ) == 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*value = *p;
|
|
Packit |
47f805 |
return p+1;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Now try to match it.
|
|
Packit |
47f805 |
for( i=0; i
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
assert( strlen( entity[i].str ) == entity[i].strLength );
|
|
Packit |
47f805 |
*value = entity[i].chr;
|
|
Packit |
47f805 |
return ( p + entity[i].strLength );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// So it wasn't an entity, its unrecognized, or something like that.
|
|
Packit |
47f805 |
*value = *p; // Don't put back the last one, since we return it!
|
|
Packit |
47f805 |
return p+1;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bool TiXmlBase::StringEqual( const char* p,
|
|
Packit |
47f805 |
const char* tag,
|
|
Packit |
47f805 |
bool ignoreCase )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
assert( p );
|
|
Packit |
47f805 |
if ( !p || !*p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
assert( 0 );
|
|
Packit |
47f805 |
return false;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( tolower( *p ) == tolower( *tag ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
const char* q = p;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (ignoreCase)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
while ( *q && *tag && *q == *tag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
++q;
|
|
Packit |
47f805 |
++tag;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( *tag == 0 ) // Have we found the end of the tag, and everything equal?
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return true;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
while ( *q && *tag && tolower( *q ) == tolower( *tag ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
++q;
|
|
Packit |
47f805 |
++tag;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( *tag == 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return true;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return false;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlBase::ReadText( const char* p,
|
|
Packit |
47f805 |
string* text,
|
|
Packit |
47f805 |
bool trimWhiteSpace,
|
|
Packit |
47f805 |
const char* endTag,
|
|
Packit |
47f805 |
bool caseInsensitive )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*text = "";
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !trimWhiteSpace // certain tags always keep whitespace
|
|
Packit |
47f805 |
|| !condenseWhiteSpace ) // if true, whitespace is always kept
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Keep all the white space.
|
|
Packit |
47f805 |
while ( p && *p
|
|
Packit |
47f805 |
&& !StringEqual( p, endTag, caseInsensitive )
|
|
Packit |
47f805 |
)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
char c;
|
|
Packit |
47f805 |
p = GetChar( p, &c );
|
|
Packit |
47f805 |
text->append( &c, 1 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
bool whitespace = false;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Remove leading white space:
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
while ( p && *p
|
|
Packit |
47f805 |
&& !StringEqual( p, endTag, caseInsensitive ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( *p == '\r' || *p == '\n' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
whitespace = true;
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if ( isspace( *p ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
whitespace = true;
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// If we've found whitespace, add it before the
|
|
Packit |
47f805 |
// new character. Any whitespace just becomes a space.
|
|
Packit |
47f805 |
if ( whitespace )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
text->append( " ", 1 );
|
|
Packit |
47f805 |
whitespace = false;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
char c;
|
|
Packit |
47f805 |
p = GetChar( p, &c );
|
|
Packit |
47f805 |
text->append( &c, 1 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return p + strlen( endTag );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
void TiXmlDocument::StreamIn( std::istream* in, std::string* tag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// The basic issue with a document is that we don't know what we're
|
|
Packit |
47f805 |
// streaming. Read something presumed to be a tag (and hope), then
|
|
Packit |
47f805 |
// identify it, and call the appropriate stream method on the tag.
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// This "pre-streaming" will never read the closing ">" so the
|
|
Packit |
47f805 |
// sub-tag can orient itself.
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !StreamTo( in, '<', tag ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
SetError( TIXML_ERROR_PARSING_EMPTY );
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
while ( in->good() )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int tagIndex = tag->length();
|
|
Packit |
47f805 |
while ( in->good() && in->peek() != '>' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int c = in->get();
|
|
Packit |
47f805 |
(*tag) += (char) c;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( in->good() )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// We now have something we presume to be a node of
|
|
Packit |
47f805 |
// some sort. Identify it, and call the node to
|
|
Packit |
47f805 |
// continue streaming.
|
|
Packit |
47f805 |
TiXmlNode* node = Identify( tag->c_str() + tagIndex );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( node )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
node->StreamIn( in, tag );
|
|
Packit |
47f805 |
bool isElement = node->ToElement() != 0;
|
|
Packit |
47f805 |
delete node;
|
|
Packit |
47f805 |
node = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// If this is the root element, we're done. Parsing will be
|
|
Packit |
47f805 |
// done by the >> operator.
|
|
Packit |
47f805 |
if ( isElement )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
SetError( TIXML_ERROR );
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
// We should have returned sooner.
|
|
Packit |
47f805 |
SetError( TIXML_ERROR );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlDocument::Parse( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Parse away, at the document level. Since a document
|
|
Packit |
47f805 |
// contains nothing but other tags, most of what happens
|
|
Packit |
47f805 |
// here is skipping white space.
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// In this variant (as opposed to stream and Parse) we
|
|
Packit |
47f805 |
// read everything we can.
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !p || !*p || !( p = SkipWhiteSpace( p ) ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
SetError( TIXML_ERROR_DOCUMENT_EMPTY );
|
|
Packit |
47f805 |
return false;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
while ( p && *p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
TiXmlNode* node = Identify( p );
|
|
Packit |
47f805 |
if ( node )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
p = node->Parse( p );
|
|
Packit |
47f805 |
LinkEndChild( node );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
// All is well.
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
TiXmlNode* TiXmlNode::Identify( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
TiXmlNode* returnNode = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
if( !p || !*p || *p != '<' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
TiXmlDocument* doc = GetDocument();
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !p || !*p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// What is this thing?
|
|
Packit |
47f805 |
// - Elements start with a letter or underscore, but xml is reserved.
|
|
Packit |
47f805 |
// - Comments:
|
|
Packit |
47f805 |
// - Decleration:
|
|
Packit |
47f805 |
// - Everthing else is unknown to tinyxml.
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* xmlHeader = { "
|
|
Packit |
47f805 |
const char* commentHeader = { "
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( StringEqual( p, xmlHeader, true ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
#ifdef DEBUG_PARSER
|
|
Packit |
47f805 |
TIXML_LOG( "XML parsing Declaration\n" );
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
returnNode = new TiXmlDeclaration();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if ( isalpha( *(p+1) )
|
|
Packit |
47f805 |
|| *(p+1) == '_' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
#ifdef DEBUG_PARSER
|
|
Packit |
47f805 |
TIXML_LOG( "XML parsing Element\n" );
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
returnNode = new TiXmlElement( "" );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if ( StringEqual( p, commentHeader, false ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
#ifdef DEBUG_PARSER
|
|
Packit |
47f805 |
TIXML_LOG( "XML parsing Comment\n" );
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
returnNode = new TiXmlComment();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
#ifdef DEBUG_PARSER
|
|
Packit |
47f805 |
TIXML_LOG( "XML parsing Unknown\n" );
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
returnNode = new TiXmlUnknown();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( returnNode )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Set the parent, so it can report errors
|
|
Packit |
47f805 |
returnNode->parent = this;
|
|
Packit |
47f805 |
//p = returnNode->Parse( p );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( doc )
|
|
Packit |
47f805 |
doc->SetError( TIXML_ERROR_OUT_OF_MEMORY );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return returnNode;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
void TiXmlElement::StreamIn( std::istream* in, std::string* tag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// We're called with some amount of pre-parsing. That is, some of "this"
|
|
Packit |
47f805 |
// element is in "tag". Go ahead and stream to the closing ">"
|
|
Packit |
47f805 |
while( in->good() )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int c = in->get();
|
|
Packit |
47f805 |
(*tag) += (char) c ;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( c == '>' )
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( tag->length() < 3 ) return;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
|
|
Packit |
47f805 |
// If not, identify and stream.
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( tag->at( tag->length() - 1 ) == '>'
|
|
Packit |
47f805 |
&& tag->at( tag->length() - 2 ) == '/' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// All good!
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if ( tag->at( tag->length() - 1 ) == '>' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// There is more. Could be:
|
|
Packit |
47f805 |
// text
|
|
Packit |
47f805 |
// closing tag
|
|
Packit |
47f805 |
// another node.
|
|
Packit |
47f805 |
for ( ;; )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
StreamWhiteSpace( in, tag );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Do we have text?
|
|
Packit |
47f805 |
if ( in->peek() != '<' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Yep, text.
|
|
Packit |
47f805 |
TiXmlText text( "" );
|
|
Packit |
47f805 |
text.StreamIn( in, tag );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// What follows text is a closing tag or another node.
|
|
Packit |
47f805 |
// Go around again and figure it out.
|
|
Packit |
47f805 |
continue;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// We now have either a closing tag...or another node.
|
|
Packit |
47f805 |
// We should be at a "<", regardless.
|
|
Packit |
47f805 |
if ( !in->good() ) return;
|
|
Packit |
47f805 |
assert( in->peek() == '<' );
|
|
Packit |
47f805 |
int tagIndex = tag->length();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bool closingTag = false;
|
|
Packit |
47f805 |
bool firstCharFound = false;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
for( ;; )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( !in->good() )
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
int c = in->peek();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( c == '>' )
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
*tag += c;
|
|
Packit |
47f805 |
in->get();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
firstCharFound = true;
|
|
Packit |
47f805 |
if ( c == '/' )
|
|
Packit |
47f805 |
closingTag = true;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
// If it was a closing tag, then read in the closing '>' to clean up the input stream.
|
|
Packit |
47f805 |
// If it was not, the streaming will be done by the tag.
|
|
Packit |
47f805 |
if ( closingTag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int c = in->get();
|
|
Packit |
47f805 |
assert( c == '>' );
|
|
Packit |
47f805 |
*tag += c;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// We are done, once we've found our closing tag.
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// If not a closing tag, id it, and stream.
|
|
Packit |
47f805 |
const char* tagloc = tag->c_str() + tagIndex;
|
|
Packit |
47f805 |
TiXmlNode* node = Identify( tagloc );
|
|
Packit |
47f805 |
if ( !node )
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
node->StreamIn( in, tag );
|
|
Packit |
47f805 |
delete node;
|
|
Packit |
47f805 |
node = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// No return: go around from the beginning: text, closing tag, or node.
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlElement::Parse( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
TiXmlDocument* document = GetDocument();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !p || !*p || *p != '<' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT );
|
|
Packit |
47f805 |
return false;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p+1 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Read the name.
|
|
Packit |
47f805 |
p = ReadName( p, &value );
|
|
Packit |
47f805 |
if ( !p || !*p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME );
|
|
Packit |
47f805 |
return false;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
string endTag = "</";
|
|
Packit |
47f805 |
endTag += value;
|
|
Packit |
47f805 |
endTag += ">";
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Check for and read attributes. Also look for an empty
|
|
Packit |
47f805 |
// tag or an end tag.
|
|
Packit |
47f805 |
while ( p && *p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
if ( !p || !*p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
if ( *p == '/' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
// Empty tag.
|
|
Packit |
47f805 |
if ( *p != '>' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return (p+1);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if ( *p == '>' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Done with attributes (if there were any.)
|
|
Packit |
47f805 |
// Read the value -- which can include other
|
|
Packit |
47f805 |
// elements -- read the end tag, and return.
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
p = ReadValue( p ); // Note this is an Element method, and will set the error if one happens.
|
|
Packit |
47f805 |
if ( !p || !*p )
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// We should find the end tag now
|
|
Packit |
47f805 |
if ( StringEqual( p, endTag.c_str(), false ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
p += endTag.length();
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Try to read an element:
|
|
Packit |
47f805 |
TiXmlAttribute attrib;
|
|
Packit |
47f805 |
attrib.SetDocument( document );
|
|
Packit |
47f805 |
p = attrib.Parse( p );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !p || !*p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
SetAttribute( attrib.Name(), attrib.Value() );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlElement::ReadValue( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
TiXmlDocument* document = GetDocument();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Read in text and elements in any order.
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
while ( p && *p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// string text;
|
|
Packit |
47f805 |
// while ( p && *p && *p != '<' )
|
|
Packit |
47f805 |
// {
|
|
Packit |
47f805 |
// text += (*p);
|
|
Packit |
47f805 |
// ++p;
|
|
Packit |
47f805 |
// }
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( *p != '<' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Take what we have, make a text element.
|
|
Packit |
47f805 |
TiXmlText* textNode = new TiXmlText( "" );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !textNode )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p = textNode->Parse( p );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !textNode->Blank() )
|
|
Packit |
47f805 |
LinkEndChild( textNode );
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
delete textNode;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// We hit a '<'
|
|
Packit |
47f805 |
// Have we hit a new element or an end tag?
|
|
Packit |
47f805 |
if ( StringEqual( p, "</", false ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
TiXmlNode* node = Identify( p );
|
|
Packit |
47f805 |
if ( node )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
p = node->Parse( p );
|
|
Packit |
47f805 |
LinkEndChild( node );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
void TiXmlUnknown::StreamIn( std::istream* in, std::string* tag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
while ( in->good() )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int c = in->get();
|
|
Packit |
47f805 |
(*tag) += c;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( c == '>' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// All is well.
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlUnknown::Parse( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
TiXmlDocument* document = GetDocument();
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
if ( !p || !*p || *p != '<' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
value = "";
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
while ( p && *p && *p != '>' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
value += *p;
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
if ( *p == '>' )
|
|
Packit |
47f805 |
return p+1;
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
void TiXmlComment::StreamIn( std::istream* in, std::string* tag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
while ( in->good() )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int c = in->get();
|
|
Packit |
47f805 |
(*tag) += c;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( c == '>'
|
|
Packit |
47f805 |
&& tag->at( tag->length() - 2 ) == '-'
|
|
Packit |
47f805 |
&& tag->at( tag->length() - 3 ) == '-' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// All is well.
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlComment::Parse( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
TiXmlDocument* document = GetDocument();
|
|
Packit |
47f805 |
value = "";
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
const char* startTag = "
|
|
Packit |
47f805 |
const char* endTag = "-->";
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( !StringEqual( p, startTag, false ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
document->SetError( TIXML_ERROR_PARSING_COMMENT );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
p += strlen( startTag );
|
|
Packit |
47f805 |
p = ReadText( p, &value, false, endTag, false );
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlAttribute::Parse( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
if ( !p || !*p ) return 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Read the name, the '=' and the value.
|
|
Packit |
47f805 |
p = ReadName( p, &name );
|
|
Packit |
47f805 |
if ( !p || !*p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
if ( !p || !*p || *p != '=' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
++p; // skip '='
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
if ( !p || !*p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* end;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( *p == '\'' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
end = "\'";
|
|
Packit |
47f805 |
p = ReadText( p, &value, false, end, false );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if ( *p == '"' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
end = "\"";
|
|
Packit |
47f805 |
p = ReadText( p, &value, false, end, false );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// All attribute values should be in single or double quotes.
|
|
Packit |
47f805 |
// But this is such a common error that the parser will try
|
|
Packit |
47f805 |
// its best, even without them.
|
|
Packit |
47f805 |
value = "";
|
|
Packit |
47f805 |
while ( p && *p // existence
|
|
Packit |
47f805 |
&& !isspace( *p ) && *p != '\n' && *p != '\r' // whitespace
|
|
Packit |
47f805 |
&& *p != '/' && *p != '>' ) // tag end
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
value += *p;
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
void TiXmlText::StreamIn( std::istream* in, std::string* tag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
while ( in->good() )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int c = in->peek();
|
|
Packit |
47f805 |
if ( c == '<' )
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
(*tag) += c;
|
|
Packit |
47f805 |
in->get();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlText::Parse( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
value = "";
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//TiXmlDocument* doc = GetDocument();
|
|
Packit |
47f805 |
bool ignoreWhite = true;
|
|
Packit |
47f805 |
// if ( doc && !doc->IgnoreWhiteSpace() ) ignoreWhite = false;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* end = "<";
|
|
Packit |
47f805 |
p = ReadText( p, &value, ignoreWhite, end, false );
|
|
Packit |
47f805 |
if ( p )
|
|
Packit |
47f805 |
return p-1; // don't truncate the '<'
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
void TiXmlDeclaration::StreamIn( std::istream* in, std::string* tag )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
while ( in->good() )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int c = in->get();
|
|
Packit |
47f805 |
(*tag) += c;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( c == '>' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// All is well.
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
const char* TiXmlDeclaration::Parse( const char* p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
// Find the beginning, find the end, and look for
|
|
Packit |
47f805 |
// the stuff in-between.
|
|
Packit |
47f805 |
TiXmlDocument* document = GetDocument();
|
|
Packit |
47f805 |
if ( !p || !*p || !StringEqual( p, "
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION );
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p += 5;
|
|
Packit |
47f805 |
// const char* start = p+5;
|
|
Packit |
47f805 |
// const char* end = strstr( start, "?>" );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
version = "";
|
|
Packit |
47f805 |
encoding = "";
|
|
Packit |
47f805 |
standalone = "";
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
while ( p && *p )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if ( *p == '>' )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
return p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p = SkipWhiteSpace( p );
|
|
Packit |
47f805 |
if ( StringEqual( p, "version", true ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// p += 7;
|
|
Packit |
47f805 |
TiXmlAttribute attrib;
|
|
Packit |
47f805 |
p = attrib.Parse( p );
|
|
Packit |
47f805 |
version = attrib.Value();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if ( StringEqual( p, "encoding", true ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// p += 8;
|
|
Packit |
47f805 |
TiXmlAttribute attrib;
|
|
Packit |
47f805 |
p = attrib.Parse( p );
|
|
Packit |
47f805 |
encoding = attrib.Value();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if ( StringEqual( p, "standalone", true ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// p += 10;
|
|
Packit |
47f805 |
TiXmlAttribute attrib;
|
|
Packit |
47f805 |
p = attrib.Parse( p );
|
|
Packit |
47f805 |
standalone = attrib.Value();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Read over whatever it is.
|
|
Packit |
47f805 |
while( p && *p && *p != '>' && !isspace( *p ) )
|
|
Packit |
47f805 |
++p;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
bool TiXmlText::Blank() const
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
for ( unsigned i=0; i
|
|
Packit |
47f805 |
if ( !isspace( value[i] ) )
|
|
Packit |
47f805 |
return false;
|
|
Packit |
47f805 |
return true;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|