Parcourir la source

added path conversion code for unicode on windows

Daniel Löber il y a 7 ans
Parent
commit
2f93cd77f8
3 fichiers modifiés avec 42 ajouts et 36 suppressions
  1. 2 1
      code/DefaultIOStream.cpp
  2. 40 29
      code/DefaultIOSystem.cpp
  3. 0 6
      include/assimp/DefaultIOSystem.h

+ 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
 #if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
         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)
             return 0;
         mCachedSize = (size_t) (fileStat.st_size);

+ 40 - 29
code/DefaultIOSystem.cpp

@@ -54,31 +54,37 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <stdlib.h>
 #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.
 bool DefaultIOSystem::Exists( const char* pFile) const
 {
+#ifdef _WIN32
+    wchar_t fileName16[PATHLIMIT];
+    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);
+#endif
     return true;
 }
 
@@ -88,10 +94,17 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
 {
     ai_assert(NULL != strFile);
     ai_assert(NULL != strMode);
-
-    FILE* file = ::fopen( strFile, strMode);
-    if( NULL == file)
-        return NULL;
+    FILE* file;
+#ifdef _WIN32
+    wchar_t fileName16[PATHLIMIT];
+    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);
+#endif
+    if (nullptr == file)
+        return nullptr;
 
     return new DefaultIOStream(file, (std::string) strFile);
 }
@@ -121,25 +134,23 @@ bool IOSystem::ComparePaths (const char* one, const char* second) const
     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
-inline void MakeAbsolutePath (const char* in, char* _out)
+inline static void MakeAbsolutePath (const char* in, char* _out)
 {
     ai_assert(in && _out);
-    char* ret;
 #if defined( _MSC_VER ) || defined( __MINGW32__ )
-    ret = ::_fullpath( _out, in, PATHLIMIT );
+    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);
+    }
 #else
     // use realpath
-    ret = realpath(in, _out);
+    char* ret = realpath(in, _out);
 #endif
     if(!ret) {
         // preserve the input path, maybe someone else is able to fix

+ 0 - 6
include/assimp/DefaultIOSystem.h

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