Unify extension check for importers.

This enables proper checking for all kinds of extensions (including the
ones with multiple dots) for all importers and internal usage.
This commit is contained in:
Marco Feuerstein
2023-07-04 09:25:45 +02:00
parent e08cb0b5b8
commit 506baa21e6
3 changed files with 34 additions and 35 deletions

View File

@@ -229,27 +229,30 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
const char *ext0,
const char *ext1,
const char *ext2) {
std::string::size_type pos = pFile.find_last_of('.');
// no file extension - can't read
if (pos == std::string::npos) {
return false;
std::set<std::string> extensions;
for (const char* ext : {ext0, ext1, ext2}) {
if (ext == nullptr) continue;
extensions.emplace(ext);
}
return HasExtension(pFile, extensions);
}
const char *ext_real = &pFile[pos + 1];
if (!ASSIMP_stricmp(ext_real, ext0)) {
return true;
// ------------------------------------------------------------------------------------------------
// Check for file extension
/*static*/ bool BaseImporter::HasExtension(const std::string &pFile, const std::set<std::string> &extensions) {
// CAUTION: Do not just search for the extension!
// GetExtension() returns the part after the *last* dot, but some extensions
// have dots inside them, e.g. ogre.mesh.xml. Compare the entire end of the
// string.
for (std::set<std::string>::const_iterator it = extensions.cbegin(); it != extensions.cend(); ++it) {
// Yay for C++<20 not having std::string::ends_with()
const std::string extension = "." + *it;
if (extension.length() > pFile.length()) continue;
// Possible optimization: Fetch the lowercase filename!
if (0 == ASSIMP_stricmp(pFile.c_str() + pFile.length() - extension.length(), extension.c_str())) {
return true;
}
}
// check for other, optional, file extensions
if (ext1 && !ASSIMP_stricmp(ext_real, ext1)) {
return true;
}
if (ext2 && !ASSIMP_stricmp(ext_real, ext2)) {
return true;
}
return false;
}

View File

@@ -637,24 +637,10 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) {
std::set<std::string> extensions;
pimpl->mImporter[a]->GetExtensionList(extensions);
// CAUTION: Do not just search for the extension!
// GetExtension() returns the part after the *last* dot, but some extensions have dots
// inside them, e.g. ogre.mesh.xml. Compare the entire end of the string.
for (std::set<std::string>::const_iterator it = extensions.cbegin(); it != extensions.cend(); ++it) {
// Yay for C++<20 not having std::string::ends_with()
std::string extension = "." + *it;
if (extension.length() <= pFile.length()) {
// Possible optimization: Fetch the lowercase filename!
if (0 == ASSIMP_stricmp(pFile.c_str() + pFile.length() - extension.length(), extension.c_str())) {
ImporterAndIndex candidate = { pimpl->mImporter[a], a };
possibleImporters.push_back(candidate);
break;
}
}
if (BaseImporter::HasExtension(pFile, extensions)) {
ImporterAndIndex candidate = { pimpl->mImporter[a], a };
possibleImporters.push_back(candidate);
}
}
// If just one importer supports this extension, pick it and close the case.