Exemple #1
0
void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const
{
	TIXML_STRING buffer;
	PutString( value, &buffer );
	fprintf( cfile, "%s", buffer.c_str() );
}
Exemple #2
0
bool TiXmlDocument::LoadBuffer( char* buffer, long size, 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 = size;

	// 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;

	memcpy(buf, buffer, 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;
}
  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;
}


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.
      char buf[ 32 ];
      sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
      outString->append( buf, strlen( buf ) );
      ++i;
    }
    else
    {
      char realc = (char) c;
      outString->append( &realc, 1 );
      ++i;
    }
  }
}
Exemple #5
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;
		}
	}
}
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;
}
Exemple #7
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;
}
Exemple #8
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;
	}
	*/
    #define BLANK_LINE_COMMENT_MAGIC "##BLANK-LINE##"
    bool bUseBlankLineMagic = true;

	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;

    bool bInComment = false;
    bool bInTag = false;
    bool bEmptyLine = false;
    int iNewLineCount = 0;
    bool bOnlyWhiteSpaceChars = false;

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

 		if ( *p == 0xa || *p == 0xd )
        {
            if ( bEmptyLine && !bInTag && !bInComment && bUseBlankLineMagic )
                iNewLineCount++;
            bEmptyLine = true;
        }

		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
        if ( *p == ' ' ||  *p == '\t' )
        {
            // White space
			++p;
        }
		else {
            if ( strncmp ( p, "<!--", 4 ) == 0 )
                bInComment = true;     // Entering comment
            else
            if ( strncmp ( p, "-->", 3 ) == 0 )
                bInComment = false;     // Leaving comment

            if ( strncmp ( p, "<", 1 ) == 0 )
            {
                bInTag = true;     // Entering tag
                // If preceeding text contains only white space, save the blank lines as comments
                if ( bOnlyWhiteSpaceChars )
                {
                    for ( int i = 0 ; i < iNewLineCount ; i++ )
                    {
                        data.append( "<!--" BLANK_LINE_COMMENT_MAGIC "-->" );
                    }
                    bOnlyWhiteSpaceChars = false;
                    iNewLineCount = 0;
                }
            }
            else
            if ( strncmp ( p, ">", 1 ) == 0 )
            {
                bInTag = false;     // Leaving tag
                // Start of possible white space area containing blank lines
                bOnlyWhiteSpaceChars = true;
                iNewLineCount = 0;
            }
            else
                bOnlyWhiteSpaceChars = false;

            bEmptyLine = false;
			++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;
}
Exemple #9
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;
		}
	}
}
Exemple #10
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;

    // reading in binary mode so that tinyxml can normalize the EOL
    FILE* file = fopen( value.c_str (), "rb" );

    if ( file )
    {
        // 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 );

        // 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 ) {
        //if ( fread( buf, 1, length, file ) != (size_t)length ) {
            SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
            fclose( file );
            return false;
        }
        fclose( file );

        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;
    }
    SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
    return false;
}
Exemple #11
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;
}
Exemple #12
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;
        }
    }
}
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;
}
Exemple #14
0
	{
		if ( strcmp( node->name.c_str(), name ) == 0 )
			return node;
	}
	return 0;
}
*/

#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 );
	out << printer.Str();

	return out;
}
	{
		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;
}


#ifdef TIXML_USE_STL	
std::generic_string & operator<< (std::generic_string& out, const TiXmlNode& base )
{
Exemple #16
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;
		}
	}
}
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;
}
Exemple #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 = 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 );
				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() );
				delete attrib;
				return 0;
			}

			attributeSet.Add( attrib );
		}
	}
	return p;
}
Exemple #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() );
  }
}