Exemple #1
0
void TiXmlText::Print( FileOps *f, int depth ) const
{
	const char *newLine = "\n";
	const char *tabSpacer = "   ";
	const char *start = "<![CDATA[";
	const char *end = "]]>\n";
	assert( f );
	if ( cdata )
	{
		int i;
		f->write(newLine, strlen(newLine), 1);
		for ( i=0; i<depth; i++ ) {
			f->write(tabSpacer, 3, 1);
		}
		f->write(start, strlen(start), 1);
		f->write(value.c_str(), value.size(), 1);
		f->write(end, strlen(end), 1);
	}
	else
	{
		TIXML_STRING buffer;
		EncodeString( value, &buffer );
		f->write(buffer.c_str(), buffer.size(), 1);
	}
}
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;
}