Przeglądaj źródła

Merge pull request #1652 from assimp/loebl-iosystem-patch

Loebl iosystem patch
Kim Kulling 7 lat temu
rodzic
commit
dd3cb74b21

+ 2 - 1
code/DefaultIOStream.cpp

@@ -123,7 +123,8 @@ size_t DefaultIOStream::FileSize() const
         // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
         // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
 #if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
 #if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
         struct __stat64 fileStat;
         struct __stat64 fileStat;
-        int err = _stat64(  mFilename.c_str(), &fileStat );
+        //using fileno + fstat avoids having to handle the filename
+        int err = _fstat64(  _fileno(mFile), &fileStat );
         if (0 != err)
         if (0 != err)
             return 0;
             return 0;
         mCachedSize = (size_t) (fileStat.st_size);
         mCachedSize = (size_t) (fileStat.st_size);

+ 75 - 30
code/DefaultIOSystem.cpp

@@ -54,31 +54,49 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <stdlib.h>
 #include <stdlib.h>
 #endif
 #endif
 
 
-using namespace Assimp;
+#ifdef _WIN32
+#include <windows.h>
+#endif
 
 
-// ------------------------------------------------------------------------------------------------
-// Constructor.
-DefaultIOSystem::DefaultIOSystem()
-{
-    // nothing to do here
-}
+using namespace Assimp;
 
 
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-DefaultIOSystem::~DefaultIOSystem()
-{
-    // nothing to do here
-}
+// maximum path length
+// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
+#ifdef PATH_MAX
+#   define PATHLIMIT PATH_MAX
+#else
+#   define PATHLIMIT 4096
+#endif
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Tests for the existence of a file at the given path.
 // Tests for the existence of a file at the given path.
 bool DefaultIOSystem::Exists( const char* pFile) const
 bool DefaultIOSystem::Exists( const char* pFile) const
 {
 {
+#ifdef _WIN32
+    wchar_t fileName16[PATHLIMIT];
+
+    bool isUnicode = IsTextUnicode(pFile, strlen(pFile), NULL);
+    if (isUnicode) {
+
+        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
+        struct _stat64 filestat;
+        if (0 != _wstat64(fileName16, &filestat)) {
+            return false;
+        }
+    } else {
+        FILE* file = ::fopen(pFile, "rb");
+        if (!file)
+            return false;
+
+        ::fclose(file);
+    }
+#else
     FILE* file = ::fopen( pFile, "rb");
     FILE* file = ::fopen( pFile, "rb");
     if( !file)
     if( !file)
         return false;
         return false;
 
 
     ::fclose( file);
     ::fclose( file);
+#endif
     return true;
     return true;
 }
 }
 
 
@@ -88,10 +106,22 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
 {
 {
     ai_assert(NULL != strFile);
     ai_assert(NULL != strFile);
     ai_assert(NULL != strMode);
     ai_assert(NULL != strMode);
-
-    FILE* file = ::fopen( strFile, strMode);
-    if( NULL == file)
-        return NULL;
+    FILE* file;
+#ifdef _WIN32
+    wchar_t fileName16[PATHLIMIT];
+    bool isUnicode = IsTextUnicode(strFile, strlen(strFile), NULL );
+    if (isUnicode) {
+        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
+        std::string mode8(strMode);
+        file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
+    } else {
+        file = ::fopen(strFile, strMode);
+    }
+#else
+    file = ::fopen(strFile, strMode);
+#endif
+    if (nullptr == file)
+        return nullptr;
 
 
     return new DefaultIOStream(file, (std::string) strFile);
     return new DefaultIOStream(file, (std::string) strFile);
 }
 }
@@ -121,32 +151,47 @@ bool IOSystem::ComparePaths (const char* one, const char* second) const
     return !ASSIMP_stricmp(one,second);
     return !ASSIMP_stricmp(one,second);
 }
 }
 
 
-// maximum path length
-// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
-#ifdef PATH_MAX
-#   define PATHLIMIT PATH_MAX
-#else
-#   define PATHLIMIT 4096
-#endif
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Convert a relative path into an absolute path
 // Convert a relative path into an absolute path
-inline void MakeAbsolutePath (const char* in, char* _out)
+inline static void MakeAbsolutePath (const char* in, char* _out)
 {
 {
     ai_assert(in && _out);
     ai_assert(in && _out);
-    char* ret;
 #if defined( _MSC_VER ) || defined( __MINGW32__ )
 #if defined( _MSC_VER ) || defined( __MINGW32__ )
-    ret = ::_fullpath( _out, in, PATHLIMIT );
+    bool isUnicode = IsTextUnicode(in, strlen(in), NULL);
+    if (isUnicode) {
+        wchar_t out16[PATHLIMIT];
+        wchar_t in16[PATHLIMIT];
+        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT);
+        wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT);
+        if (ret) {
+            WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr);
+        }
+        if (!ret) {
+            // preserve the input path, maybe someone else is able to fix
+            // the path before it is accessed (e.g. our file system filter)
+            DefaultLogger::get()->warn("Invalid path: " + std::string(in));
+            strcpy(_out, in);
+        }
+
+    } else {
+        char* ret = :: _fullpath(_out, in, PATHLIMIT);
+        if (!ret) {
+            // preserve the input path, maybe someone else is able to fix
+            // the path before it is accessed (e.g. our file system filter)
+            DefaultLogger::get()->warn("Invalid path: " + std::string(in));
+            strcpy(_out, in);
+        }
+    }
 #else
 #else
     // use realpath
     // use realpath
-    ret = realpath(in, _out);
-#endif
+    char* ret = realpath(in, _out);
     if(!ret) {
     if(!ret) {
         // preserve the input path, maybe someone else is able to fix
         // preserve the input path, maybe someone else is able to fix
         // the path before it is accessed (e.g. our file system filter)
         // the path before it is accessed (e.g. our file system filter)
         DefaultLogger::get()->warn("Invalid path: "+std::string(in));
         DefaultLogger::get()->warn("Invalid path: "+std::string(in));
         strcpy(_out,in);
         strcpy(_out,in);
     }
     }
+#endif
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------

+ 0 - 6
include/assimp/DefaultIOSystem.h

@@ -52,12 +52,6 @@ namespace Assimp    {
 class ASSIMP_API DefaultIOSystem : public IOSystem
 class ASSIMP_API DefaultIOSystem : public IOSystem
 {
 {
 public:
 public:
-    /** Constructor. */
-    DefaultIOSystem();
-
-    /** Destructor. */
-    ~DefaultIOSystem();
-
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Tests for the existence of a file at the given path. */
     /** Tests for the existence of a file at the given path. */
     bool Exists( const char* pFile) const;
     bool Exists( const char* pFile) const;