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 ); Parse( data.c_str(), 0 ); if ( Error() ) return false; else return true; } SetError( TIXML_ERROR_OPENING_FILE, 0, 0 ); return false; }
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; }