Quellcode durchsuchen

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.
Marco Feuerstein vor 2 Jahren
Ursprung
Commit
506baa21e6
3 geänderte Dateien mit 34 neuen und 35 gelöschten Zeilen
  1. 21 18
      code/Common/BaseImporter.cpp
  2. 3 17
      code/Common/Importer.cpp
  3. 10 0
      include/assimp/BaseImporter.h

+ 21 - 18
code/Common/BaseImporter.cpp

@@ -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;
-    }
-
-    const char *ext_real = &pFile[pos + 1];
-    if (!ASSIMP_stricmp(ext_real, ext0)) {
-        return true;
-    }
-
-    // check for other, optional, file extensions
-    if (ext1 && !ASSIMP_stricmp(ext_real, ext1)) {
-        return true;
+    std::set<std::string> extensions;
+    for (const char* ext : {ext0, ext1, ext2}) {
+        if (ext == nullptr) continue;
+        extensions.emplace(ext);
     }
+    return HasExtension(pFile, extensions);
+}
 
-    if (ext2 && !ASSIMP_stricmp(ext_real, ext2)) {
-        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;
+        }
     }
-
     return false;
 }
 

+ 3 - 17
code/Common/Importer.cpp

@@ -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.

+ 10 - 0
include/assimp/BaseImporter.h

@@ -275,6 +275,16 @@ public: // static utilities
             const char *ext1 = nullptr,
             const char *ext2 = nullptr);
 
+    // -------------------------------------------------------------------
+    /** @brief Check whether a file has one of the passed file extensions
+     *  @param pFile Input file
+     *  @param extensions Extensions to check for. Lowercase characters only, no dot!
+     *  @note Case-insensitive
+     */
+    static bool HasExtension(
+            const std::string &pFile,
+            const std::set<std::string> &extensions);
+
     // -------------------------------------------------------------------
     /** @brief Extract file extension from a string
      *  @param pFile Input file