Ejemplo n.º 1
0
void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const
{
	TIXML_STRING buffer;
	PutString( value, &buffer );
	generic_fprintf( cfile, TEXT("%s"), buffer.c_str() );
}
Ejemplo n.º 2
0
bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
{
	if ( !file ) 
	{
		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
		return false;
	}

	// Delete the existing data:
	Clear();
	location.Clear();

	// Get the file size, so we can pre-allocate the string. HUGE speed impact.
	long length = 0;
	fseek( file, 0, SEEK_END );
	length = ftell( file );
	fseek( file, 0, SEEK_SET );

	// Strange case, but good to handle up front.
	if ( length <= 0 )
	{
		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
		return false;
	}

	// If we have a file, assume it is all one big XML file, and read it in.
	// The document parser may decide the document ends sooner than the entire file, however.
	TIXML_STRING data;
	data.reserve( length );

	// Subtle bug here. TinyXml did use fgets. But from the XML spec:
	// 2.11 End-of-Line Handling
	// <snip>
	// <quote>
	// ...the XML processor MUST behave as if it normalized all line breaks in external 
	// parsed entities (including the document entity) on input, before parsing, by translating 
	// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
	// a single #xA character.
	// </quote>
	//
	// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
	// Generally, you expect fgets to translate from the convention of the OS to the c/unix
	// convention, and not work generally.

	/*
	while( fgets( buf, sizeof(buf), file ) )
	{
		data += buf;
	}
	*/

	char* buf = new char[ length+1 ];
	buf[0] = 0;

	if ( fread( buf, length, 1, file ) != 1 ) {
		delete [] buf;
		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
		return false;
	}

	const char* lastPos = buf;
	const char* p = buf;

	buf[length] = 0;
	while( *p ) {
		assert( p < (buf+length) );
		if ( *p == 0xa ) {
			// Newline character. No special rules for this. Append all the characters
			// since the last string, and include the newline.
			data.append( lastPos, (p-lastPos+1) );	// append, include the newline
			++p;									// move past the newline
			lastPos = p;							// and point to the new buffer (may be 0)
			assert( p <= (buf+length) );
		}
		else if ( *p == 0xd ) {
			// Carriage return. Append what we have so far, then
			// handle moving forward in the buffer.
			if ( (p-lastPos) > 0 ) {
				data.append( lastPos, p-lastPos );	// do not add the CR
			}
			data += (char)0xa;						// a proper newline

			if ( *(p+1) == 0xa ) {
				// Carriage return - new line sequence
				p += 2;
				lastPos = p;
				assert( p <= (buf+length) );
			}
			else {
				// it was followed by something else...that is presumably characters again.
				++p;
				lastPos = p;
				assert( p <= (buf+length) );
			}
		}
		else {
			++p;
		}
	}
	// Handle any left over characters.
	if ( p-lastPos ) {
		data.append( lastPos, p-lastPos );
	}		
	delete [] buf;
	buf = 0;

	Parse( data.c_str(), 0, encoding );

	if (  XMLError() )
        return false;
    else
		return true;
}
Ejemplo n.º 3
0
void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
{
	int i=0;

	while( i<(int)str.length() )
	{
		int c = str[i];

		if (    c == '&' 
		     && i < ( (int)str.length() - 2 )
			 && str[i+1] == '#'
			 && str[i+2] == 'x' )
		{
			// Hexadecimal character reference.
			// Pass through unchanged.
			// &#xA9;	-- copyright symbol, for example.
			while ( i<(int)str.length() )
			{
				outString->append( str.c_str() + i, 1 );
				++i;
				if ( str[i] == ';' )
					break;
			}
		}
		else if ( c == '&' )
		{
			outString->append( entity[0].str, entity[0].strLength );
			++i;
		}
		else if ( c == '<' )
		{
			outString->append( entity[1].str, entity[1].strLength );
			++i;
		}
		else if ( c == '>' )
		{
			outString->append( entity[2].str, entity[2].strLength );
			++i;
		}
		else if ( c == '\"' )
		{
			outString->append( entity[3].str, entity[3].strLength );
			++i;
		}
		else if ( c == '\'' )
		{
			outString->append( entity[4].str, entity[4].strLength );
			++i;
		}
		else if ( c < 32 || c > 126 )
		{
			// Easy pass at non-alpha/numeric/symbol
			// 127 is the delete key. Below 32 is symbolic.
			TCHAR buf[ 32 ];
			wsprintf( buf, TEXT("&#x%04X;"), ((_TUCHAR)c) & 0xffff );
			outString->append( buf, lstrlen( buf ) );
			++i;
		}
		else
		{
			TCHAR realc = (TCHAR) c;
			outString->append( &realc, 1 );
			++i;
		}
	}
}
Ejemplo n.º 4
0
bool TiXmlDocument::LoadFile( const TCHAR* filename )
{
	// Delete the existing data:
	Clear();
	location.Clear();

	// There was a really terrifying little bug here. The code:
	//		value = filename
	// in the STL case, cause the assignment method of the std::generic_string to
	// be called. What is strange, is that the std::generic_string had the same
	// address as it's c_str() method, and so bad things happen. Looks
	// like a bug in the Microsoft STL implementation.
	// See STL_STRING_BUG above.
	// Fixed with the StringToBuffer class.
	value = filename;

	FILE* file = generic_fopen( value.c_str (), TEXT("r") );

	if ( file )
	{
		// Get the file size, so we can pre-allocate the generic_string. HUGE speed impact.
		long length = 0;
		fseek( file, 0, SEEK_END );
		length = ftell( file );
		fseek( file, 0, SEEK_SET );

		// Strange case, but good to handle up front.
		if ( length == 0 )
		{
			fclose( file );
			return false;
		}

		// If we have a file, assume it is all one big XML file, and read it in.
		// The document parser may decide the document ends sooner than the entire file, however.
		TIXML_STRING data;
		data.reserve( length );

		const int BUF_SIZE = 2048;
		TCHAR buf[BUF_SIZE];

		while( generic_fgets( buf, BUF_SIZE, file ) )
		{
			data += buf;
		}
		fclose( file );

		//input is in UTF-8, so transformation is needed to UTF-16 used by windows for TCHAR in unicode mode
		std::vector<char> inputdataInUTF8(data.size()+1); //+1 for the null termination
		size_t datalength = wcstombs(inputdataInUTF8.data(), data.c_str(), data.size());
		int transformedDataCharCount = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)inputdataInUTF8.data(), -1, nullptr, 0);
		std::vector<wchar_t> transformedData(transformedDataCharCount+1); //+1 for the null termination
		transformedDataCharCount = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)inputdataInUTF8.data(), -1, transformedData.data(), transformedDataCharCount);
		if(transformedDataCharCount > 0)
		{
			//replace the original data with the new tranformed one, on success ot transformation otherwise go with old style data
			data.clear();
			data = transformedData.data();
		}
		Parse( data.c_str(), 0 );

		if (  Error() )
            return false;
        else
			return true;
	}
	SetError( TIXML_ERROR_OPENING_FILE, 0, 0 );
	return false;
}
Ejemplo n.º 5
0
void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
{
  TIXML_STRING::size_type i=0;

        while( i < static_cast<TIXML_STRING::size_type>(str.length()) )
        {
                int c = str[i];

                if (    c == '&' 
                        && i < ( static_cast<TIXML_STRING::size_type>(str.length() - 2 ))
                         && str[i+1] == '#'
                         && str[i+2] == 'x' )
                {
                        // Hexadecimal character reference.
                        // Pass through unchanged.
                        // &#xA9;       -- copyright symbol, for example.
                  while ( i<static_cast<TIXML_STRING::size_type>(str.length()) )
                        {
                                outString->append( str.c_str() + i, 1 );
                                ++i;
                                if ( str[i] == ';' )
                                        break;
                        }
                }
                else if ( c == '&' )
                {
                        outString->append( entity[0].str, entity[0].strLength );
                        ++i;
                }
                else if ( c == '<' )
                {
                        outString->append( entity[1].str, entity[1].strLength );
                        ++i;
                }
                else if ( c == '>' )
                {
                        outString->append( entity[2].str, entity[2].strLength );
                        ++i;
                }
                else if ( c == '\"' )
                {
                        outString->append( entity[3].str, entity[3].strLength );
                        ++i;
                }
                else if ( c == '\'' )
                {
                        outString->append( entity[4].str, entity[4].strLength );
                        ++i;
                }
                else if ( c < 32 || c > 126 )
                {
                        // Easy pass at non-alpha/numeric/symbol
                        // 127 is the delete key. Below 32 is symbolic.
                        char buf[ 32 ];
                        sprintf( buf, "&#x%02X;", static_cast<unsigned> ( c & 0xff ) );
                        outString->append( buf, strlen( buf ) );
                        ++i;
                }
                else
                {
                  char realc = static_cast<char>( c);
                        outString->append( &realc, 1 );
                        ++i;
                }
        }
}
Ejemplo n.º 6
0
{
	TiXmlAttribute* node;

	for( node = sentinel.next; node != &sentinel; node = node->next )
	{
		if ( node->name == name )
			return node;
	}
	return 0;
}


#ifdef TIXML_USE_STL	
TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
{
	TIXML_STRING tag;
	tag.reserve( 8 * 1000 );
	base.StreamIn( &in, &tag );

	base.Parse( tag.c_str(), 0 );
	return in;
}
#endif


TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
{
	base.StreamOut (& out);
	return out;
}
Ejemplo n.º 7
0
void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
{
	int i=0;

	while( i<(int)str.length() )
	{
		unsigned char c = (unsigned char) str[i];

		if (    c == '&' 
		     && i < ( (int)str.length() - 2 )
			 && str[i+1] == '#'
			 && str[i+2] == 'x' )
		{
			// Hexadecimal character reference.
			// Pass through unchanged.
			// &#xA9;	-- copyright symbol, for example.
			//
			// The -1 is a bug fix from Rob Laveaux. It keeps
			// an overflow from happening if there is no ';'.
			// There are actually 2 ways to exit this loop -
			// while fails (error case) and break (semicolon found).
			// However, there is no mechanism (currently) for
			// this function to return an error.
			while ( i<(int)str.length()-1 )
			{
				outString->append( str.c_str() + i, 1 );
				++i;
				if ( str[i] == ';' )
					break;
			}
		}
		else if ( c == '&' )
		{
			outString->append( entity[0].str, entity[0].strLength );
			++i;
		}
		else if ( c == '<' )
		{
			outString->append( entity[1].str, entity[1].strLength );
			++i;
		}
		else if ( c == '>' )
		{
			outString->append( entity[2].str, entity[2].strLength );
			++i;
		}
		else if ( c == '\"' )
		{
			outString->append( entity[3].str, entity[3].strLength );
			++i;
		}
		else if ( c == '\'' )
		{
			outString->append( entity[4].str, entity[4].strLength );
			++i;
		}
		else if ( c == 0x0d && ( (int)str.length() - 1 )
				 && str[i+1] == 0x0a)
		{
			// insert \n
			*outString += '\n';
			++i;
			++i;
		}
		else if (isspace (c))
		{
			// pass through unchagend
			*outString += (char) c;	// somewhat more efficient function call.
			++i;
		}
		else if (iscntrl (c)) // ( c < 32)
		{
			std::cerr << "WARNING: control character 0x"
					<< std::hex << std::setw(2) << std::setfill('0') << (unsigned)c
					<< " in text input at character "
					<< std::dec << std::setw(0) << i
					<< std::endl;
			
			++i;
		}
		else
		{
			// just pass these through, since we've
			// declared an encoding that presumably allows
			// them
			*outString += (char) c;	// somewhat more efficient function call.
			//char realc = (char) c;
			//outString->append( &realc, 1 );
			++i;
		}
	}
}
Ejemplo n.º 8
0
void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
{
    int i=0;

    while( i<(int)str.length() )
    {
        unsigned char c = (unsigned char) str[i];

        if (    c == '&'
                && i < ( (int)str.length() - 2 )
                && str[i+1] == '#'
                && str[i+2] == 'x' )
        {
            // Hexadecimal character reference.
            // Pass through unchanged.
            // &#xA9;	-- copyright symbol, for example.
            //
            // The -1 is a bug fix from Rob Laveaux. It keeps
            // an overflow from happening if there is no ';'.
            // There are actually 2 ways to exit this loop -
            // while fails (error case) and break (semicolon found).
            // However, there is no mechanism (currently) for
            // this function to return an error.
            while ( i<(int)str.length()-1 )
            {
                outString->append( str.c_str() + i, 1 );
                ++i;
                if ( str[i] == ';' )
                    break;
            }
        }
        else if ( c == '&' )
        {
            outString->append( entity[0].str, entity[0].strLength );
            ++i;
        }
        else if ( c == '<' )
        {
            outString->append( entity[1].str, entity[1].strLength );
            ++i;
        }
        else if ( c == '>' )
        {
            outString->append( entity[2].str, entity[2].strLength );
            ++i;
        }
        else if ( c == '\"' )
        {
            outString->append( entity[3].str, entity[3].strLength );
            ++i;
        }
        else if ( c == '\'' )
        {
            outString->append( entity[4].str, entity[4].strLength );
            ++i;
        }
        else if ( c < 32 )
        {
            // Easy pass at non-alpha/numeric/symbol
            // Below 32 is symbolic.
            char buf[ 32 ];

#if defined(TIXML_SNPRINTF)
            TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
#else
            sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
#endif

            //*ME:	warning C4267: convert 'size_t' to 'int'
            //*ME:	Int-Cast to make compiler happy ...
            outString->append( buf, (int)strlen( buf ) );
            ++i;
        }
        else
        {
            //char realc = (char) c;
            //outString->append( &realc, 1 );
            *outString += (char) c;	// somewhat more efficient function call.
            ++i;
        }
    }
}
Ejemplo n.º 9
0
void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
{
    int i=0;

    while( i<(int)str.length() )
    {
        unsigned char c = (unsigned char) str[i];

        if (    c == '&'
                && i < ( (int)str.length() - 2 )
                && str[i+1] == '#'
                && str[i+2] == 'x' )
        {

            while ( i<(int)str.length()-1 )
            {
                outString->append( str.c_str() + i, 1 );
                ++i;
                if ( str[i] == ';' )
                    break;
            }
        }
        else if ( c == '&' )
        {
            outString->append( entity[0].str, entity[0].strLength );
            ++i;
        }
        else if ( c == '<' )
        {
            outString->append( entity[1].str, entity[1].strLength );
            ++i;
        }
        else if ( c == '>' )
        {
            outString->append( entity[2].str, entity[2].strLength );
            ++i;
        }
        else if ( c == '\"' )
        {
            outString->append( entity[3].str, entity[3].strLength );
            ++i;
        }
        else if ( c == '\'' )
        {
            outString->append( entity[4].str, entity[4].strLength );
            ++i;
        }
        else if ( c < 32 )
        {

            char buf[ 32 ];

#if defined(TIXML_SNPRINTF)
            TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
#else
            sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
#endif


            outString->append( buf, (int)strlen( buf ) );
            ++i;
        }
        else
        {

            *outString += (char) c;
            ++i;
        }
    }
}
Ejemplo n.º 10
0
bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
{
    if ( !file )
    {
        SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
        return false;
    }


    Clear();
    location.Clear();


    long length = 0;
    fseek( file, 0, SEEK_END );
    length = ftell( file );
    fseek( file, 0, SEEK_SET );


    if ( length <= 0 )
    {
        SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
        return false;
    }


    TIXML_STRING data;
    data.reserve( length );



    char* buf = new char[ length+1 ];
    buf[0] = 0;

    if ( fread( buf, length, 1, file ) != 1 ) {
        delete [] buf;
        SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
        return false;
    }

    const char* lastPos = buf;
    const char* p = buf;

    buf[length] = 0;
    while( *p ) {
        assert( p < (buf+length) );
        if ( *p == 0xa ) {

            data.append( lastPos, (p-lastPos+1) );
            ++p;
            lastPos = p;
            assert( p <= (buf+length) );
        }
        else if ( *p == 0xd ) {

            if ( (p-lastPos) > 0 ) {
                data.append( lastPos, p-lastPos );
            }
            data += (char)0xa;

            if ( *(p+1) == 0xa ) {

                p += 2;
                lastPos = p;
                assert( p <= (buf+length) );
            }
            else {

                ++p;
                lastPos = p;
                assert( p <= (buf+length) );
            }
        }
        else {
            ++p;
        }
    }

    if ( p-lastPos ) {
        data.append( lastPos, p-lastPos );
    }
    delete [] buf;
    buf = 0;

    Parse( data.c_str(), 0, encoding );

    if (  Error() )
        return false;
    else
        return true;
}
Ejemplo n.º 11
0
{
	TiXmlAttribute* node;

	for( node = sentinel.next; node != &sentinel; node = node->next )
	{
		if ( node->name == name )
			return node;
	}
	return 0;
}


#ifdef TIXML_USE_STL	
TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
{
	TIXML_STRING tag;
	tag.reserve( 8 * 1000 );
	base.StreamIn( &in, &tag );

	base.Parse( tag.c_str() );
	return in;
}
#endif


TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
{
	base.StreamOut (& out);
	return out;
}
Ejemplo n.º 12
0
bool TiXmlDocument::ReadFromMemory( const char* pBuf, size_t sz, TiXmlEncoding encoding)
{
    // Delete the existing data:
    Clear();
    location.Clear();

    // Get the file size, so we can pre-allocate the string. HUGE speed impact.
    long length = (long) sz;

    // Strange case, but good to handle up front.
    if ( length == 0 )
    {
        SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
        return false;
    }

    // If we have a file, assume it is all one big XML file, and read it in.
    // The document parser may decide the document ends sooner than the entire file, however.
    TIXML_STRING data;
    data.reserve( length );


    char* buf = new char[ length+1 ];
    memset(buf,0,length+1);

    memcpy(buf, pBuf, length);

    const char* lastPos = buf;
    const char* p = buf;

    buf[length] = 0;
    while( *p ) {
        assert( p < (buf+length) );
        if ( *p == 0xa ) {
            // Newline character. No special rules for this. Append all the characters
            // since the last string, and include the newline.
            data.append( lastPos, (p-lastPos+1) );  // append, include the newline
            ++p;                                    // move past the newline
            lastPos = p;                            // and point to the new buffer (may be 0)
            assert( p <= (buf+length) );
        }
        else if ( *p == 0xd ) {
            // Carriage return. Append what we have so far, then
            // handle moving forward in the buffer.
            if ( (p-lastPos) > 0 ) {
                data.append( lastPos, p-lastPos );  // do not add the CR
            }
            data += (char)0xa;                      // a proper newline

            if ( *(p+1) == 0xa ) {
                // Carriage return - new line sequence
                p += 2;
                lastPos = p;
                assert( p <= (buf+length) );
            }
            else {
                // it was followed by something else...that is presumably characters again.
                ++p;
                lastPos = p;
                assert( p <= (buf+length) );
            }
        }
        else {
            ++p;
        }
    }
    // Handle any left over characters.
    if ( p-lastPos ) {
        data.append( lastPos, p-lastPos );
    }
    delete [] buf;
    buf = 0;

    Parse( data.c_str(), 0, encoding );

    if (  Error() )
        return false;
    else
        return true;
}
Ejemplo n.º 13
0
void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
{
	int i=0;

	while( i<(int)str.length() )
	{
		unsigned char c = (unsigned char) str[i];

		if (    c == '&' 
		     && i < ( (int)str.length() - 2 )
			 && str[i+1] == '#'
			 && str[i+2] == 'x' )
		{
			// Hexadecimal character reference.
			// Pass through unchanged.
			// &#xA9;	-- copyright symbol, for example.
			while ( i<(int)str.length() )
			{
				outString->append( str.c_str() + i, 1 );
				++i;
				if ( str[i] == ';' )
					break;
			}
		}
		else if ( c == '&' )
		{
			outString->append( entity[0].str, entity[0].strLength );
			++i;
		}
		else if ( c == '<' )
		{
			outString->append( entity[1].str, entity[1].strLength );
			++i;
		}
		else if ( c == '>' )
		{
			outString->append( entity[2].str, entity[2].strLength );
			++i;
		}
		else if ( c == '\"' )
		{
			outString->append( entity[3].str, entity[3].strLength );
			++i;
		}
		else if ( c == '\'' )
		{
			outString->append( entity[4].str, entity[4].strLength );
			++i;
		}
		else if ( c < 32 )
		{
			// Easy pass at non-alpha/numeric/symbol
			// Below 32 is symbolic.
			char buf[ 32 ];
			sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
			outString->append( buf, strlen( buf ) );
			++i;
		}
		else
		{
			// Assume everthing else is unicode. c should never actually 
			// be out of the range of 0-255. Else something has gone strange.

			//char realc = (char) c;
			//outString->append( &realc, 1 );
			*outString += (char) c;	// somewhat more efficient function call.
			++i;
		}
	}
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
const TCHAR* TiXmlElement::Parse( const TCHAR* 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 TCHAR* 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 (TEXT("</"));
	endTag += value;
	endTag += TEXT(">");

	// 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 TCHAR* 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;
}
Ejemplo n.º 16
0
TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
{
    TiXmlAttribute* attrib = Find( _name );
    if ( !attrib ) {
        attrib = new TiXmlAttribute();
        Add( attrib );
        attrib->SetName( _name );
    }
    return attrib;
}


#ifdef TIXML_USE_STL
std::istream& operator>> (std::istream & in, TiXmlNode & base)
{
    TIXML_STRING tag;
    tag.reserve( 8 * 1000 );
    base.StreamIn( &in, &tag );

    base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
    return in;
}
#endif


#ifdef TIXML_USE_STL
std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
{
    TiXmlPrinter printer;
    printer.SetStreamPrinting();
    base.Accept( &printer );
Ejemplo n.º 17
0
bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding )
{
	// Delete the existing data:
	Clear();
	location.Clear();

	// There was a really terrifying little bug here. The code:
	//		value = filename
	// in the STL case, cause the assignment method of the std::string to
	// be called. What is strange, is that the std::string had the same
	// address as it's c_str() method, and so bad things happen. Looks
	// like a bug in the Microsoft STL implementation.
	// See STL_STRING_BUG above.
	// Fixed with the StringToBuffer class.
	value = filename;

	//SECURITY-UPDATE:2/3/07
	//FILE* file = fopen( value.c_str (), "r" );
	//if ( file )
	//{

	FILE *file=NULL;
	errno_t err=0;

	err=fopen_s(&file,value.c_str (), "r");

	if(file && err==0)
	{
		// Get the file size, so we can pre-allocate the string. HUGE speed impact.
		long length = 0;
		fseek( file, 0, SEEK_END );
		length = ftell( file );
		fseek( file, 0, SEEK_SET );

		// Strange case, but good to handle up front.
		if ( length == 0 )
		{
			fclose( file );
			return false;
		}

		// If we have a file, assume it is all one big XML file, and read it in.
		// The document parser may decide the document ends sooner than the entire file, however.
		TIXML_STRING data;
		data.reserve( length );

		const int BUF_SIZE = 2048;
		char buf[BUF_SIZE];

		while( fgets( buf, BUF_SIZE, file ) )
		{
			data += buf;
		}
		fclose( file );

		Parse( data.c_str(), 0, encoding );

		if (  Error() )
            return false;
        else
			return true;
	}
	SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
	return false;
}
Ejemplo n.º 18
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;
	endTag += ">";

	// 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
			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
			{
				p += endTag.length();
				return p;
			}
			else
			{
				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
				return 0;
			}
		}
		else
		{
			// Try to read an attribute:
			TiXmlAttribute* attrib = XNEW(TiXmlAttribute)(); //new TiXmlAttribute();
			if ( !attrib )
			{
				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
				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 );
				XDELETE(attrib); //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 )
			{
				node->SetValue( attrib->Value() );
				XDELETE(attrib); //delete attrib;
				return 0;
			}

			attributeSet.Add( attrib );
		}
	}
	return p;
}
Ejemplo n.º 19
0
// <-- Strange class for a bug fix. Search for STL_STRING_BUG
TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str )
  : buffer(new char[str.length() + 1]) {
  if ( buffer ) {
    strcpy( buffer, str.c_str() );
  }
}