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()
|
||||
{
|
||||
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.
|
||||
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)
|
||||
|
@ -95,6 +130,68 @@ bool FileUtilsWin32::isAbsolutePath(const std::string& strPath)
|
|||
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()
|
||||
{
|
||||
// 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 bool isFileExist(const std::string& strFilePath);
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue