Преглед на файлове

# fix potential memory leak in MD5Loader.cpp.
- unify formatting in the aforementioned loader.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@875 67173fc5-114c-0410-ac8e-9d2fd5bffc1f

aramis_acg преди 14 години
родител
ревизия
e2e5463845
променени са 1 файла, в които са добавени 30 реда и са изтрити 19 реда
  1. 30 19
      code/MD5Loader.cpp

+ 30 - 19
code/MD5Loader.cpp

@@ -63,6 +63,7 @@ using namespace Assimp;
 // Constructor to be privately used by Importer
 // Constructor to be privately used by Importer
 MD5Importer::MD5Importer()
 MD5Importer::MD5Importer()
 : configNoAutoLoad (false)
 : configNoAutoLoad (false)
+, mBuffer()
 {}
 {}
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -79,8 +80,9 @@ bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 	if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
 	if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
 		return true;
 		return true;
 	else if (!extension.length() || checkSig)	{
 	else if (!extension.length() || checkSig)	{
-		if (!pIOHandler)
+		if (!pIOHandler) {
 			return true;
 			return true;
+		}
 		const char* tokens[] = {"MD5Version"};
 		const char* tokens[] = {"MD5Version"};
 		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
 		return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
 	}
 	}
@@ -114,7 +116,7 @@ void MD5Importer::InternReadFile( const std::string& pFile,
 	bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
 	bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
 
 
 	// remove the file extension
 	// remove the file extension
-	std::string::size_type pos = pFile.find_last_of('.');
+	const std::string::size_type pos = pFile.find_last_of('.');
 	mFile = (std::string::npos == pos ? pFile : pFile.substr(0,pos+1));
 	mFile = (std::string::npos == pos ? pFile : pFile.substr(0,pos+1));
 
 
 	const std::string extension = GetExtension(pFile);
 	const std::string extension = GetExtension(pFile);
@@ -125,7 +127,7 @@ void MD5Importer::InternReadFile( const std::string& pFile,
 		else if (configNoAutoLoad || extension == "md5anim") {
 		else if (configNoAutoLoad || extension == "md5anim") {
 			// determine file extension and process just *one* file
 			// determine file extension and process just *one* file
 			if (extension.length() == 0) {
 			if (extension.length() == 0) {
-				/* fixme */
+				throw DeadlyImportError("Failure, need file extension to determine MD5 part type");
 			}
 			}
 			if (extension == "md5anim") {
 			if (extension == "md5anim") {
 				LoadMD5AnimFile();
 				LoadMD5AnimFile();
@@ -139,29 +141,36 @@ void MD5Importer::InternReadFile( const std::string& pFile,
 			LoadMD5AnimFile();
 			LoadMD5AnimFile();
 		}
 		}
 	}
 	}
-	catch ( std::exception&) {
-		// XXX use more idiomatic RAII solution
+	catch ( ... ) { // std::exception, Assimp::DeadlyImportError
 		UnloadFileFromMemory();
 		UnloadFileFromMemory();
 		throw;
 		throw;
 	}
 	}
 
 
 	// make sure we have at least one file
 	// make sure we have at least one file
-	if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera)
-		throw DeadlyImportError("Failed to read valid contents from this MD5* file");
+	if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera) {
+		throw DeadlyImportError("Failed to read valid contents out of this MD5* file");
+	}
 
 
-	// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
+	// Now rotate the whole scene 90 degrees around the x axis to match our internal coordinate system
 	pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
 	pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
 		0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
 		0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
 
 
 	// the output scene wouldn't pass the validation without this flag
 	// the output scene wouldn't pass the validation without this flag
-	if (!bHadMD5Mesh)
+	if (!bHadMD5Mesh) {
 		pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
 		pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
+	}
+
+	// clean the instance -- the BaseImporter instance may be reused later.
+	UnloadFileFromMemory();
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Load a file into a memory buffer
 // Load a file into a memory buffer
 void MD5Importer::LoadFileIntoMemory (IOStream* file)
 void MD5Importer::LoadFileIntoMemory (IOStream* file)
 {
 {
+	// unload the previous buffer, if any
+	UnloadFileFromMemory();
+
 	ai_assert(NULL != file);
 	ai_assert(NULL != file);
 	fileSize = (unsigned int)file->FileSize();
 	fileSize = (unsigned int)file->FileSize();
 
 
@@ -207,8 +216,9 @@ void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
 	for (FaceList::const_iterator iter = meshSrc.mFaces.begin(),iterEnd = meshSrc.mFaces.end();iter != iterEnd;++iter){
 	for (FaceList::const_iterator iter = meshSrc.mFaces.begin(),iterEnd = meshSrc.mFaces.end();iter != iterEnd;++iter){
 		const aiFace& face = *iter;
 		const aiFace& face = *iter;
 		for (unsigned int i = 0; i < 3;++i) {
 		for (unsigned int i = 0; i < 3;++i) {
-			if (face.mIndices[0] >= meshSrc.mVertices.size())
+			if (face.mIndices[0] >= meshSrc.mVertices.size()) {
 				throw DeadlyImportError("MD5MESH: Invalid vertex index");
 				throw DeadlyImportError("MD5MESH: Invalid vertex index");
+			}
 
 
 			if (abHad[face.mIndices[i]])	{
 			if (abHad[face.mIndices[i]])	{
 				// generate a new vertex
 				// generate a new vertex
@@ -459,8 +469,9 @@ void MD5Importer::LoadMD5MeshFile ()
 						throw DeadlyImportError("MD5MESH: Invalid weight index");
 						throw DeadlyImportError("MD5MESH: Invalid weight index");
 
 
 					MD5::WeightDesc& desc = meshSrc.mWeights[w];
 					MD5::WeightDesc& desc = meshSrc.mWeights[w];
-					if ( desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON)
+					if ( desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON) {
 						continue;
 						continue;
+					}
 
 
 					const float fNewWeight = desc.mWeight / fSum; 
 					const float fNewWeight = desc.mWeight / fSum; 
 
 
@@ -478,8 +489,9 @@ void MD5Importer::LoadMD5MeshFile ()
 			}
 			}
 
 
 			// undo our nice offset tricks ...
 			// undo our nice offset tricks ...
-			for (unsigned int p = 0; p < mesh->mNumBones;++p)
+			for (unsigned int p = 0; p < mesh->mNumBones;++p) {
 				mesh->mBones[p]->mWeights -= mesh->mBones[p]->mNumWeights;
 				mesh->mBones[p]->mWeights -= mesh->mBones[p]->mNumWeights;
+			}
 		}
 		}
 
 
 		delete[] piCount;
 		delete[] piCount;
@@ -528,8 +540,6 @@ void MD5Importer::LoadMD5MeshFile ()
 		mesh->mMaterialIndex = n++;
 		mesh->mMaterialIndex = n++;
 	}
 	}
 #endif
 #endif
-	// delete the file again
-	UnloadFileFromMemory();
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -605,15 +615,17 @@ void MD5Importer::LoadMD5AnimFile ()
 
 
 					// translational component
 					// translational component
 					for (unsigned int i = 0; i < 3; ++i) {
 					for (unsigned int i = 0; i < 3; ++i) {
-						if ((*iter2).iFlags & (1u << i))
+						if ((*iter2).iFlags & (1u << i)) {
 							vKey->mValue[i] =  *fpCur++;
 							vKey->mValue[i] =  *fpCur++;
+						}
 						else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
 						else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
 					}
 					}
 
 
 					// orientation component
 					// orientation component
 					for (unsigned int i = 0; i < 3; ++i) {
 					for (unsigned int i = 0; i < 3; ++i) {
-						if ((*iter2).iFlags & (8u << i))
+						if ((*iter2).iFlags & (8u << i)) {
 							vTemp[i] =  *fpCur++;
 							vTemp[i] =  *fpCur++;
+						}
 						else vTemp[i] = pcBaseFrame->vRotationQuat[i];
 						else vTemp[i] = pcBaseFrame->vRotationQuat[i];
 					}
 					}
 
 
@@ -643,8 +655,6 @@ void MD5Importer::LoadMD5AnimFile ()
 			}
 			}
 		}
 		}
 	}
 	}
-	// delete the file again
-	UnloadFileFromMemory();
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -667,8 +677,9 @@ void MD5Importer::LoadMD5CameraFile ()
 	// load the camera animation data from the parse tree
 	// load the camera animation data from the parse tree
 	MD5::MD5CameraParser cameraParser(parser.mSections);
 	MD5::MD5CameraParser cameraParser(parser.mSections);
 
 
-	if (cameraParser.frames.empty())
+	if (cameraParser.frames.empty()) {
 		throw DeadlyImportError("MD5CAMERA: No frames parsed");
 		throw DeadlyImportError("MD5CAMERA: No frames parsed");
+	}
 
 
 	std::vector<unsigned int>& cuts = cameraParser.cuts;
 	std::vector<unsigned int>& cuts = cameraParser.cuts;
 	std::vector<MD5::CameraAnimFrameDesc>& frames = cameraParser.frames;
 	std::vector<MD5::CameraAnimFrameDesc>& frames = cameraParser.frames;