mirror of https://github.com/axmolengine/axmol.git
closed #2440: Files with Non-ascii path can't be found on Windows.
This commit is contained in:
parent
1c2b89e431
commit
2566f74cd7
|
@ -43,6 +43,36 @@ static void _checkPath()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// D:/aaa/bbb/ccc/ddd/abc.txt --> D:\aaa\bbb\ccc\ddd\abc.txt
|
||||||
|
static inline std::string convertPathFormatToWindowStyle(const std::string& path)
|
||||||
|
{
|
||||||
|
std::string ret = path;
|
||||||
|
int len = ret.length();
|
||||||
|
for (int i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
if (ret[i] == '/')
|
||||||
|
{
|
||||||
|
ret[i] = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// D:\aaa\bbb\ccc\ddd\abc.txt --> D:/aaa/bbb/ccc/ddd/abc.txt
|
||||||
|
static inline std::string convertPathFormatToUnixStyle(const std::string& path)
|
||||||
|
{
|
||||||
|
std::string ret = path;
|
||||||
|
int len = ret.length();
|
||||||
|
for (int i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
if (ret[i] == '\\')
|
||||||
|
{
|
||||||
|
ret[i] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
FileUtils* FileUtils::getInstance()
|
FileUtils* FileUtils::getInstance()
|
||||||
{
|
{
|
||||||
if (s_sharedFileUtils == NULL)
|
if (s_sharedFileUtils == NULL)
|
||||||
|
@ -81,7 +111,12 @@ bool FileUtilsWin32::isFileExist(const std::string& strFilePath)
|
||||||
{ // Not absolute path, add the default root path at the beginning.
|
{ // Not absolute path, add the default root path at the beginning.
|
||||||
strPath.insert(0, _defaultResRootPath);
|
strPath.insert(0, _defaultResRootPath);
|
||||||
}
|
}
|
||||||
return GetFileAttributesA(strPath.c_str()) != -1 ? true : false;
|
|
||||||
|
convertPathFormatToWindowStyle(strPath);
|
||||||
|
WCHAR wszBuf[MAX_PATH] = {0};
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, strPath.c_str(), -1, wszBuf, sizeof(wszBuf));
|
||||||
|
|
||||||
|
return GetFileAttributesW(wszBuf) != -1 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileUtilsWin32::isAbsolutePath(const std::string& strPath)
|
bool FileUtilsWin32::isAbsolutePath(const std::string& strPath)
|
||||||
|
@ -95,6 +130,68 @@ bool FileUtilsWin32::isAbsolutePath(const std::string& strPath)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char* FileUtilsWin32::getFileData(const char* filename, const char* mode, unsigned long* size)
|
||||||
|
{
|
||||||
|
unsigned char * pBuffer = NULL;
|
||||||
|
CCASSERT(filename != NULL && size != NULL && mode != NULL, "Invalid parameters.");
|
||||||
|
*size = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// read the file from hardware
|
||||||
|
std::string fullPath = fullPathForFilename(filename);
|
||||||
|
|
||||||
|
WCHAR wszBuf[MAX_PATH] = {0};
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, fullPath.c_str(), -1, wszBuf, sizeof(wszBuf));
|
||||||
|
|
||||||
|
|
||||||
|
HANDLE fileHandle = ::CreateFileW(wszBuf, GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, NULL);
|
||||||
|
CC_BREAK_IF(fileHandle == INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
|
*size = ::GetFileSize(fileHandle, NULL);
|
||||||
|
|
||||||
|
pBuffer = new unsigned char[*size];
|
||||||
|
DWORD sizeRead = 0;
|
||||||
|
BOOL successed = FALSE;
|
||||||
|
successed = ::ReadFile(fileHandle, pBuffer, *size, &sizeRead, NULL);
|
||||||
|
::CloseHandle(fileHandle);
|
||||||
|
|
||||||
|
if (!successed)
|
||||||
|
{
|
||||||
|
CC_SAFE_DELETE_ARRAY(pBuffer);
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
if (! pBuffer)
|
||||||
|
{
|
||||||
|
std::string msg = "Get data from file(";
|
||||||
|
// Gets error code.
|
||||||
|
DWORD errorCode = ::GetLastError();
|
||||||
|
char errorCodeBuffer[20] = {0};
|
||||||
|
snprintf(errorCodeBuffer, sizeof(errorCodeBuffer), "%d", errorCode);
|
||||||
|
|
||||||
|
msg = msg + filename + ") failed, error code is " + errorCodeBuffer;
|
||||||
|
CCLOG("%s", msg.c_str());
|
||||||
|
}
|
||||||
|
return pBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FileUtilsWin32::getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath)
|
||||||
|
{
|
||||||
|
std::string unixFileName = convertPathFormatToUnixStyle(filename);
|
||||||
|
std::string unixResolutionDirector = convertPathFormatToUnixStyle(resolutionDirectory);
|
||||||
|
std::string unixSearchPath = convertPathFormatToUnixStyle(searchPath);
|
||||||
|
|
||||||
|
return FileUtils::getPathForFilename(unixFileName, unixResolutionDirector, unixSearchPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FileUtilsWin32::getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename)
|
||||||
|
{
|
||||||
|
std::string dosDirectory = convertPathFormatToWindowStyle(strDirectory);
|
||||||
|
std::string dosFilename = convertPathFormatToWindowStyle(strFilename);
|
||||||
|
|
||||||
|
return FileUtils::getFullPathForDirectoryAndFilename(dosDirectory, dosFilename);
|
||||||
|
}
|
||||||
|
|
||||||
string FileUtilsWin32::getWritablePath()
|
string FileUtilsWin32::getWritablePath()
|
||||||
{
|
{
|
||||||
// Get full path of executable, e.g. c:\Program Files (x86)\My Game Folder\MyGame.exe
|
// Get full path of executable, e.g. c:\Program Files (x86)\My Game Folder\MyGame.exe
|
||||||
|
|
|
@ -49,6 +49,39 @@ public:
|
||||||
virtual std::string getWritablePath();
|
virtual std::string getWritablePath();
|
||||||
virtual bool isFileExist(const std::string& strFilePath);
|
virtual bool isFileExist(const std::string& strFilePath);
|
||||||
virtual bool isAbsolutePath(const std::string& strPath);
|
virtual bool isAbsolutePath(const std::string& strPath);
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Gets resource file data
|
||||||
|
*
|
||||||
|
* @param[in] filename The resource file name which contains the path.
|
||||||
|
* @param[in] pszMode The read mode of the file.
|
||||||
|
* @param[out] pSize If the file read operation succeeds, it will be the data size, otherwise 0.
|
||||||
|
* @return Upon success, a pointer to the data is returned, otherwise NULL.
|
||||||
|
* @warning Recall: you are responsible for calling delete[] on any Non-NULL pointer returned.
|
||||||
|
*/
|
||||||
|
virtual unsigned char* getFileData(const char* filename, const char* mode, unsigned long * size) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets full path for filename, resolution directory and search path.
|
||||||
|
*
|
||||||
|
* @param filename The file name.
|
||||||
|
* @param resolutionDirectory The resolution directory.
|
||||||
|
* @param searchPath The search path.
|
||||||
|
* @return The full path of the file. It will return an empty string if the full path of the file doesn't exist.
|
||||||
|
*/
|
||||||
|
virtual std::string getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets full path for the directory and the filename.
|
||||||
|
*
|
||||||
|
* @note Only iOS and Mac need to override this method since they are using
|
||||||
|
* `[[NSBundle mainBundle] pathForResource: ofType: inDirectory:]` to make a full path.
|
||||||
|
* Other platforms will use the default implementation of this method.
|
||||||
|
* @param strDirectory The directory contains the file we are looking for.
|
||||||
|
* @param strFilename The name of the file.
|
||||||
|
* @return The full path of the file, if the file can't be found, it will return an empty string.
|
||||||
|
*/
|
||||||
|
virtual std::string getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// end of platform group
|
// end of platform group
|
||||||
|
|
Loading…
Reference in New Issue